JSON, Retrofit, RecyclerView

Retrofit

  • štandardné REST API s JSON
  • keď nechceme cache, request prioritization,
  • Square’s Retrofit

Retrofit allows to use the following converters:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi
  • Protobuf: com.squareup.retrofit:converter-protobuf
  • Wire: com.squareup.retrofit:converter-wire
  • Simple XML: com.squareup.retrofit:converter-simplexml

To work with Retrofit you need basically three classes.

  • Model class which is used to map the JSON data to
  • Interfaces which defines the possible HTTP operations
  • Retrofit.Builder class - Instance which uses the interface. Builder API which allows defining the URL end point for the HTTP operation.

(Zdroj - http://vickychijwani.me/retrofit-vs-volley/)

Príklad:

zdroj: https://www.learn2crack.com/2016/02/recyclerview-json-parsing.html

build.gradle(Module:app)

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.android.support:cardview-v7:23.2.0'
    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
    testCompile 'junit:junit:4.12'
}

main_activity.xml, list_item.xml, RecyclerViewAdapter.java, AndroidVerzie.java sú rovnaké ako v predchádzajúcom programe VolleyPriklad1.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

 

list_item,xml

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    card_view:cardCornerRadius="5dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="vertical">
    <TextView
        android:id="@+id/nazov"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:textSize="18dp"
        android:textStyle="bold"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        />
    <TextView
        android:id="@+id/verzia"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New Text" />
    <TextView
        android:id="@+id/api_level"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New Text"/>
    </LinearLayout>
</android.support.v7.widget.CardView>

 

AndroidVerzie.java

public class AndroidVerzie {

    //môžeme a nemusíme použiť anotáciu SerializedName - dôležitá v prípade, keď JSON objekt propertie nie je rovnaký ako premenná

    @SerializedName("ver")

    private String ver;

    @SerializedName("name")
    private String name;

    @SerializedName("api")
    private String api;

    public AndroidVerzie(String ver, String name, String api) {
        this.ver = ver;
        this.name = name;
        this.api = api;
    }
    public String getVer() {
        return ver;
    }
    public String getName() {
        return name;
    }
    public String getApi() {
        return api;
    }
}

 

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    private ArrayList<AndroidVerzie> androidArrayList;

    public RecyclerViewAdapter( ArrayList<AndroidVerzie> androidArrayList) {
        this.androidArrayList = androidArrayList;
    }

    //onCreateViewHolder() táto metóda sa volá vždy, keď sa vytvorí nová inštancia ViewHolder, naplníme riadky
    @Override
    public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);

        return new ViewHolder(layoutView);
    }

    //voláme vždy, keď sa dáta zobrazia na obrazovke
   @Override
    public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) {
        holder.nazov.setText(androidArrayList.get(position).getName());
        holder.verzia.setText(androidArrayList.get(position).getVer());
        holder.api_level.setText(androidArrayList.get(position).getApi());
    }

    @Override
    public int getItemCount() {
        return androidArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView nazov;
        private TextView verzia;
        private TextView api_level;

        public ViewHolder(View itemView) {
            super(itemView);

            nazov = itemView.findViewById(R.id.nazov);
            verzia = itemView.findViewById(R.id.verzia);
            api_level = itemView.findViewById(R.id.api_level);
        }

    }
}

JSONResponse.java

public class JSONResponse {

    private AndroidVerzie[] android;

    public AndroidVerzie[] getAndroid() {
        return android;
    }
}

RequestInterface.java

//interface, ktorý definuje Request endpoint
public interface RequestInterface {


/*GET request na získanie JSON dát. Endpoint je definovaný v anotácií.request URL je:
http://api.learn2crack.com/android/jsonandroid ,
kde http://api.learn2crack.com je základ a android/jsonandroid je endpoint */
 
   //request je asynchrónny Call
    @GET("android/jsonandroid")

    Call<JSONResponse> getJSON();

}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private RecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recycler_view);

        //musím nastaviť zobrazovanie záznamov na Lineárne
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(layoutManager);

        nacitajJson();
    }

    private void nacitajJson(){

        //inicializácia knižnice Retrofit, nastavenie základnej URL adresy
        Retrofit retrofit = new Retrofit.Builder()

                .baseUrl("http://api.learn2crack.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        //vytvorený objekt RequestInterface
        RequestInterface request = retrofit.create(RequestInterface.class);

        //asynchrónna požiadavka (request) je vytvorený zavolaním metódy getJSON()
        Call<JSONResponse> call = request.getJSON();

        //asynchrónny request sa zavolá metódou enqueue(). Request môže byť úspečný, alebo neúspešný.
        call.enqueue(new Callback<JSONResponse>() {

            @Override
            public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {

                //JSON dáta sa získajú pomocou zavolania metódy body()
                JSONResponse jsonResponse = response.body();

                //convertujeme ArrayObject na ArrayList
                ArrayList<AndroidVerzie> data = new ArrayList<>(Arrays.asList(jsonResponse.getAndroid()));


                //RecyclerView
                adapter = new RecyclerViewAdapter(data);

                recyclerView.setAdapter(adapter);
            }

            @Override
            public void onFailure(Call<JSONResponse> call, Throwable t) {
                Log.d("Error",t.getMessage());
            }
        });
    }
}