We have already seen how to set up android retrofit library to send request to rest based web services. In this tutorial, We will see how to show the response coming from server in RecyclerView. After that, we will see some advance concept about retrofit library.
Output
Video Output
Source Code
Android Retrofit Tutorial with Example – Source code
Getting started
There are 2 sections in this tutorial.
a. Show Server Response in RecyclerView.
b. Retrofit advance concepts.
1. Show Server Response in RecyclerView
In this section, we will show response coming from server in previous tutorial to RecyclerView.
1.1 Project Structure
I have created a new package named adapter that contains adapter for RecyclerView. Also, there is a new xml file question_item.xml. Don’t worry about this new stuff. We will go through it one by one 🙂 . Finally, our project structure will be like below.
1.2 Add gradle for RecycleView in app/build.gradle
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.squareup.retrofit2:retrofit:2.0.2' compile 'com.squareup.retrofit2:converter-gson:2.0.2' compile 'com.android.support:recyclerview-v7:23.3.0' }
1.3 Add RecyclerView in 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".activity.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/questionListRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </RelativeLayout>
1.4 Create layout for a single item in RecyclerView
Create a new xml file question_item.xml in res/layout.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/positionNumber" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/link" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@android:color/darker_gray" android:layout_marginTop="5dp" android:layout_marginBottom="5dp"/> </LinearLayout>
1.5 Create an adapter for RecyclerView
Create a new package adapter in tutorialwing.com.retrofitlibrary. Then, create a class QuestionAdapter for RecyclerView and add the code below in it.
package tutorialwing.com.retrofitlibrary.adapter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.List; import tutorialwing.com.retrofitlibrary.R; import tutorialwing.com.retrofitlibrary.model.Question; public class QuestionAdapter extends RecyclerView.Adapter<QuestionAdapter.QuestionViewHolder> { private List<Question> questions; private int rowLayout; private Context context; public QuestionAdapter(List<Question> questions, int rowLayout, Context context) { this.questions = questions; this.rowLayout = rowLayout; this.context = context; } @Override public QuestionAdapter.QuestionViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false); return new QuestionViewHolder(view); } @Override public void onBindViewHolder(QuestionViewHolder holder, final int position) { holder.positionNumber.setText("Question number : " + String.valueOf(position + 1)); holder.questionTitle.setText("Title : " + questions.get(position).getTitle()); holder.link.setText("Link : " + questions.get(position).getLink()); } @Override public int getItemCount() { return questions.size(); } public static class QuestionViewHolder extends RecyclerView.ViewHolder { TextView positionNumber; TextView questionTitle; TextView link; public QuestionViewHolder(View v) { super(v); positionNumber = (TextView) v.findViewById(R.id.positionNumber); questionTitle = (TextView) v.findViewById(R.id.title); link = (TextView) v.findViewById(R.id.link); } } }
1.6 Show the Server Response in MainActivity
In MainActivity.java class, Add the code to fetch the data from server. Then, show the response in RecyclerView.
package tutorialwing.com.retrofitlibrary.activity; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import java.util.ArrayList; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import tutorialwing.com.retrofitlibrary.R; import tutorialwing.com.retrofitlibrary.adapter.QuestionAdapter; import tutorialwing.com.retrofitlibrary.model.Question; import tutorialwing.com.retrofitlibrary.model.QuestionList; import tutorialwing.com.retrofitlibrary.rest.QuestionAPIService; import tutorialwing.com.retrofitlibrary.rest.RestClient; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); QuestionAPIService apiService; RecyclerView recyclerView; QuestionAdapter adapter; List<Question> questions = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); apiService = RestClient.getClient().create(QuestionAPIService.class); recyclerView = (RecyclerView) findViewById(R.id.questionListRecyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new QuestionAdapter(questions, R.layout.question_item, getApplicationContext()); recyclerView.setAdapter(adapter); fetchQuetionList(); } private void fetchQuetionList() { Call<QuestionList> call = apiService.fetchQuestions("android"); call.enqueue(new Callback<QuestionList>() { @Override public void onResponse(Call<QuestionList> call, Response<QuestionList> response) { Log.d(TAG, "Total number of questions fetched : " + response.body().getQuestions().size()); questions.addAll(response.body().getQuestions()); adapter.notifyDataSetChanged(); } @Override public void onFailure(Call<QuestionList> call, Throwable t) { Log.e(TAG, "Got error : " + t.getLocalizedMessage()); } }); } }
1.7 Output
If you have followed the tutorial properly, you will get the output as shown above. However, you can download the source code from link given above.
2. Retrofit Advance Concepts
While defining APIService interface, we use different annotations.These annotations define how a request will be handled. For example – If you are using @GET annotation, then, Get request will be processed. If you are using @POST annotation, then, POST request will be processed.
Also, Every method must contain HTTP annotation that provides the request method and relative URL(end url). There are five built-in annotations: GET, POST, PUT, DELETE, and HEAD.
2.1 GET Annotation
@GET("end url") Call<QuestionList> getQuestionList(@Query("tagged") String tags);
2.2 POST Annotation
@POST("end url") Call<Question> postQuestion(@Body Question question);
2.3 PUT Annotation
@PUT("end url") Call<QuestionList> putQuestion(@Path("question_id") String questionId, @Body QuestionRequestBody question);
2.4 DELETE Annotation
@DELETE("end url") Call<Question> deleteQuestion(@Path("id") int questionId);
2.5 HEADER Annotation
This is used when you want to send some data in header with request. For example, to send clientToken in header of the request etc.
Retrofit provides 2 ways to define header fields – static and dynamic. Static headers can not be changed for each request. It will be fixed for every request. On the other hand, Dynamic headers must be set for each request.
2.5.1 Static headers
If you want to pass only one key-value pair, you can pass it as below.
@Headers("Cache-Control: max-age=640000") @GET("end url") Call<QuestionList> getQuestionList(@Query("tagged") String tags);
If you want to pass multiple key-value pair, then, you can pass it as below.
@Headers({ "Accept: application/vnd.yourapi.v1.full+json", "User-Agent: Your-App-Name" }) @GET("end url") Call<QuestionList> getQuestionList(@Query("tagged") String tags);
Additionally, you can also define headers in intercept method in RequestInterceptor.
package tutorialwing.com.retrofitlibrary.rest; import java.io.IOException; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RestClient { public static final String BASE_URL = "https://api.stackexchange.com"; private static Retrofit retrofit = null; public static Retrofit getClient() { if (retrofit == null) { OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); httpClient.addInterceptor(new Interceptor() { @Override public Response intercept(Interceptor.Chain chain) throws IOException { Request originalRequest = chain.request(); Request request = originalRequest.newBuilder() .header("User-Agent", "Your-App-Name") .header("Accept", "application/vnd.yourapi.v1.full+json") .method(originalRequest.method(), originalRequest.body()) .build(); return chain.proceed(request); } }); OkHttpClient client = httpClient.build(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(client) .build(); } return retrofit; } }
2.5.2 Dynamic headers
you can set headers dynamically as well. It is passed like a parameter in the header with @Header annotation.
@GET("end url") Call<QuestionList> getQuestionList(@Header("Content-Range") String contentRange, @Query("tagged") String tags);
Conclusion
Retrofit is a simple, easy to learn and use, yet powerful android library for rest based web services.You can make synchronous as well as asynchronous calls through it. You can easily send request like GET,POST,PUT, DELETE using this library. Hope this tutorial helped you.
You must be logged in to post a comment.