Ps.: JSON data is not parsed in the CardView.
Main Fragment
I used a fragment for viewing the data on every item click and these are identified by slider menu. I wrote the code for parsing JSON data using Retrofit web service.
public class Physical_Geography_Activity extends Fragment{
View viewOne;
private RecyclerView recyclerView;
private ArrayList<QAModel> dataArray;
private DataAdapter adapter;
private ProgressDialog dialog;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
viewOne=inflater.inflate(R.layout.geo_physical_layout,container,false);
recyclerView=(RecyclerView)viewOne.findViewById(R.id.card_recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(viewOne.getContext());
recyclerView.setLayoutManager(layoutManager);
loadJSON();
return viewOne;
}
private void loadJSON() {
dialog = ProgressDialog.show(getContext(),"Please wait","Loading..",true);
dialog.show();
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.myjson.com").addConverterFactory(GsonConverterFactory.create()).build();
RequestInterface requestInterface = retrofit.create(RequestInterface.class);
Call<JSONResponse> call = requestInterface.getJSON();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
dialog.dismiss();
JSONResponse jsonResponse=response.body();
dataArray = new ArrayList<QAModel>(Arrays.asList(jsonResponse.getPhysiography()));
adapter= new DataAdapter(dataArray);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});
}
}
Adapter
Custom ListView to view the data and wrote a holder class to hold the data, I used two TextViews to view the text, that is question and answer. The question and answer are dynamically changing whenever I am adding data in my remote server.
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<QAModel> arrayList;
public DataAdapter(ArrayList<QAModel> arrayList) {
this.arrayList = arrayList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.physical_card_layout,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.question.setText(arrayList.get(position).getQuestion());
holder.answer.setText(arrayList.get(position).getAnswer());
}
#Override
public int getItemCount() {
return arrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView question,answer;
public ViewHolder(View itemView) {
super(itemView);
question=(TextView)itemView.findViewById(R.id.tv_question);
answer=(TextView)itemView.findViewById(R.id.tv_answer);
}
}
}
Model
Model has one constructor and two private string variables. And I have created the setters and getters methods for getting and setting the JSON data from the remote server.
public class QAModel {
private String Question;
private String Answer;
public QAModel(String question, String answer) {
Question = question;
Answer = answer;
}
public String getQuestion() {
return Question;
}
public void setQuestion(String question) {
Question = question;
}
public String getAnswer() {
return Answer;
}
public void setAnswer(String answer) {
Answer = answer;
}
}
JSON Response
JSON Response class is written for getting the response of the model class with the method call.
public class JSONResponse {
private QAModel[] physiography;
public QAModel[] getPhysiography()
{
return physiography;
}
}
Interface
Interface has one method for getting the data from the server, that is getJSON and the interface does have the suffix url which hold the JSON data.
public interface RequestInterface {
#GET("bins/lo1md")
Call<JSONResponse> getJSON();
}
You are missing a '/' in your base URL 'https://api.myjson.com'
Please update your line
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.myjson.com").addConverterFactory(GsonConverterFactory.create()).build();
to this
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.myjson.com/").addConverterFactory(GsonConverterFactory.create()).build();
Also you need to change your model class to as below,
public class JSONResponse {
#SerializedName("physiography")
#Expose
private List<Physiography> physiography = null;
public List<Physiography> getPhysiography() {
return physiography;
}
public void setPhysiography(List<Physiography> physiography) {
this.physiography = physiography;
}
}
and
public class Physiography {
#SerializedName("answer")
#Expose
private String answer;
#SerializedName("question")
#Expose
private String question;
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
}
make adapter.notifyDataSetChanged();
Edited :
public class JSONResponse {
#SerializedName("physiography")
public List<Physiography> physiography = new ArrayList<Physiography>;
}
public class Physiography {
#SerializedName("answer")
public String answer;
#SerializedName("question")
public String question;
}
change your response class like then check it
Boom !
1) put this gradle in your project .
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.google.code.gson:gson:2.8.0'
2) make 2 models , 1st for
QAModel
public class QAModel{
#SerializedName("answer")
private String Answer;
#SerializedName("question")
private String Question;
public QAModel(String question, String answer) {
Question = question;
Answer = answer;
}
public String getQuestion() {
return Question;
}
public void setQuestion(String question) {
Question = question;
}
public String getAnswer() {
return Answer;
}
public void setAnswer(String answer) {
Answer = answer;
}
}
and 2nd for Response of server
ResponseQAModel
public class ResponseQAModel {
#SerializedName("physiography")
private List<QAModel> qaModels;
public List<QAModel> getQaModels() {
return qaModels;
}
public void setQaModels(List<QAModel> qaModels) {
this.qaModels = qaModels;
}
}
3)ApiClient where you setup your retrofit
public class ApiClient {
public static final String BASE_URL = "https://api.myjson.com/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
4) Your Routes ApiInterface
public interface ApiInterface {
#GET("/bins/lo1md")
Call<ResponseQAModel> getJSON();
}
5)Now its time to catch output ;)
private void loadGSON() {
final Call<ResponseQAModel> responseQAModelCall;
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
responseQAModelCall = apiService.getJSON();
responseQAModelCall.enqueue(new Callback<ResponseQAModel>() {
#Override
public void onResponse(Call<ResponseQAModel> call, Response<ResponseQAModel> response) {
Log.d("kkkkk",response.body().getQaModels().toString());
//responseQAMODELS contains all response pass to your adapter
List<QAModel> responseQAModels = response.body().getQaModels();
}
#Override
public void onFailure(Call<ResponseQAModel> call, Throwable t) {
}
});
}
First of all don't name your response object to something that common(JSONResponse). Name it more appropriately lets say PhysiographyResponse. Use Moshi library from squareup, it will generate JAVA objects of your JSON response.
Moshi dependency
implementation 'com.squareup.retrofit2:converter-moshi:2.3.0'
implementation 'com.squareup.moshi:moshi:1.5.0'
Data model classes -
import com.squareup.moshi.Json;
public class PhysiographyResponse {
#Json(name = "physiography")
List<QAModel> QAModel;
public List<QAModel> getQAModel() {
return QAModel;
}
public void setQAModel(List<QAModel> QAModel) {
this.QAModel = QAModel;
}
}
import com.squareup.moshi.Json;
public class QAModel {
#Json(name = "answer")
String answer;
#Json(name = "question")
String question;
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
}
Api interface
public interface RequestInterface {
#GET("bins/lo1md")
Call<PhysiographyResponse> getPhysiographyResponse();
}
Retrofit call
Call<PhysiographyResponse> call = requestInterface.getPhysiographyResponse();
call.enqueue(new Callback<PhysiographyResponse>() {
#Override
public void onResponse(Call<PhysiographyResponse> call, Response<PhysiographyResponse> response) {
dialog.dismiss();
dataArray = new ArrayList<QAModel>(Arrays.asList(resposne.getQAModel));
adapter= new DataAdapter(dataArray);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});
Related
I'm stuck somewhere in between getting json array inside a object setting it to recylerview, I have to send a key to fetch data and getting response in json array inside a object. Didn't understand solutions got here, so I'm here if Somebody can help mre understand.
////Main class
public class today_doctors extends AppCompatActivity {
viewModel_doc listViewModel;
List<model_doc> datalist;
todayDoctorAdapter adapter;
TextView clinic_name;
RecyclerView recview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_today_doctors);
recview=findViewById(R.id.rv);
recview.setLayoutManager(new LinearLayoutManager(this));
recview.addItemDecoration(new DividerItemDecoration(this, 0));
adapter=new todayDoctorAdapter(datalist);
recview.setAdapter(adapter);
clinic_name=findViewById(R.id.tvDrName);
process();
}
public void process(){
listViewModel= new ViewModelProvider(this).get(viewModel_doc.class);
listViewModel.getDatalistObserver ().observe(this, new Observer<List<model_doc>>() {
#Override
public void onChanged(List<model_doc> Models) {
if(Models!=null) {
datalist= Models;
adapter.updateList(Models);
}
else
{
recview.setVisibility(View.GONE);
Toast.makeText(today_doctors.this, "No data recieved", Toast.LENGTH_SHORT).show();
}
}
});
listViewModel.makeApiCall();
}
//////////Viewmodel class
public class viewModel_doc extends ViewModel
{
private MutableLiveData<List<model_doc>> datalist2;
public viewModel_doc(){
datalist2=new MutableLiveData<>();
}
public MutableLiveData<List<model_doc>> getDatalistObserver()
{
return datalist2;
}
public void makeApiCall()
{
apiSet apiServices= apiController.getInstance().getApi();
Call<List<model_doc>> calldoc=apiServices.getList2("ll0004");
calldoc.enqueue(new Callback<List<model_doc>>() {
#Override
public void onResponse(Call<List<model_doc>> call, Response<List<model_doc>> response) {
datalist2.postValue(response.body());
}
#Override
public void onFailure(Call<List<model_doc>> call, Throwable t) {
datalist2.postValue(null);
Log.e("Error :",t.getMessage());
}
});
}
}
///////////////////main model
public class model_doc {
String status,msg;
ArrayList<Data> data;
public model_doc(String status, String msg, ArrayList<Data> data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public String getStatus() {
return status;
}
public String getMsg() {
return msg;
}
public ArrayList<Data> getData() {
return data;
}
public static class Data {
String doctor_id;
String doctor_name;
String proposed_date;
String date;
// Getters setters
public Data(String doctor_id, String doctor_name, String proposed_date, String date) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.proposed_date = proposed_date;
this.date = date;
}
public String getDoctor_id() {
return doctor_id;
}
public String getDoctor_name() {
return doctor_name;
}
public String getProposed_date() {
return proposed_date;
}
public String getDate() {
return date;
}
}
}
////api interface
#FormUrlEncoded
#POST("doctor_list")
Call<List<model_doc>>getList2(
#Field("clinic_id") String clinic_id
);
//////////////////controller
public class apiController {
private static final String url="https://xyz.in/api/";
private static apiController clientObject;
private static Retrofit retrofit;
apiController()
{
retrofit=new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static synchronized apiController getInstance(){
if(clientObject==null)
clientObject=new apiController();
return clientObject;
}
public apiSet getApi(){
return retrofit.create(apiSet.class);
}
}
////////////recycler adapter, made some changes in main model for nested data could handle it to adapter
public class todayDoctorAdapter extends RecyclerView.Adapter<todayDoctorAdapter.viewholder>
{
List<model_doc> datalist2;
public todayDoctorAdapter(List<model_doc> list){
this.datalist2=list;}
public void updateList(List<model_doc>list){
this.datalist2=list;
notifyDataSetChanged();
}
#NonNull
#Override
public todayDoctorAdapter.viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType){
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_doctors,parent,false);
return new todayDoctorAdapter.viewholder(view);
}
#Override
public void onBindViewHolder(#NonNull todayDoctorAdapter.viewholder holder, int position){
holder.doctor_name.setText(String.format("Dr.%s", datalist2.get(position).getDoctor_app()));
holder.proposed_date.setText(String.format("Apt: %s","TODAY"));
String doc=datalist2.get(position).getDoctor_app();
holder.cv.setOnClickListener(
new View.OnClickListener(){
#Override
public void onClick(View arg0) {
Intent intent = new Intent(arg0.getContext(), PatientsUnderDoctor.class);
intent.putExtra("doc_name", doc);
arg0.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount(){
if (this.datalist2!=null){
return this.datalist2.size();
}
return 0;
}
public static class viewholder extends RecyclerView.ViewHolder{
TextView doctor_name,proposed_date;
CardView cv;
public viewholder(#NonNull View itemView) {
super(itemView);
doctor_name=itemView.findViewById(R.id.drName);
proposed_date=itemView.findViewById(R.id.apptDate);
cv=itemView.findViewById(R.id.cv_patient);
}
}
}
//////////////////json data look like this
{
"status": "success",
"msg": "Found",
"data": [
{
"doc_code": "jhjh0001",
"app_date": "2022-09-13",
"doc_name": "kjk",
"count": 1
}
]
}
I am making a simple app in which the user will able to search for books by its name, with google.com book api. For now, I wish to present a list of books with android in their name. I am doing it with Retrofit2 and RecycleView, but nothing is showing.
MainActivity:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
KnjigaAdapter knjigaAdapter;
List<KnjigaModel> listaKnjiga;
public static final String BASE_URL = "https://www.googleapis.com/books/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uzmiKomentare();
}
public void uzmiKomentare() {
Gson gson = new GsonBuilder().serializeNulls().create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
KnjigaApi knjigaApi = retrofit.create(KnjigaApi.class);
final Call<KnjigaModel> pozivZaListuKnjiga = knjigaApi.getKnjige("android");
pozivZaListuKnjiga.enqueue(new Callback<KnjigaModel>() {
#Override
public void onResponse(Call<KnjigaModel> call, Response<KnjigaModel> response) {
if (!response.isSuccessful()) {
return;
}
//generateRecycleView(WHAT TO PUT HERE!!!!);
}
#Override
public void onFailure(Call<KnjigaModel> call, Throwable t) {
Log.d("MainActivity:", t.getMessage());
}
});
}
private void generateRecycleView(List<KnjigaModel> knjige) {
listaKnjiga = new ArrayList<>();
recyclerView = findViewById(R.id.recycleview);
knjigaAdapter = new KnjigaAdapter(this, knjige);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(knjigaAdapter);
if (knjigaAdapter.getItemCount() == 0){
Log.i("List is empty: ","YES");
}
else {
Log.i("list is empty: ","No");
}
}
}
api inteface:
public interface KnjigaApi {
#GET("v1/volumes")
Call<KnjigaModel> getKnjige(#Query("q") String knjiga);
}
model class:
public class KnjigaModel {
#SerializedName("title")
#Expose
private String imeKnjige;
#SerializedName("authors")
#Expose
private String imeAutora;
#SerializedName("thumbnail")
#Expose
private String slikaKnjige;
public KnjigaModel(String imeKnjige, String imeAutora,String slikaKnjige) {
this.imeKnjige = imeKnjige;
this.imeAutora = imeAutora;
this.slikaKnjige = slikaKnjige;
}
public String getImeKnjige() {
return imeKnjige;
}
public String getImeAutora() {
return imeAutora;
}
public String getSlikaKnjige() {
return slikaKnjige;
}
}
and my adapter:
public class KnjigaAdapter extends RecyclerView.Adapter<KnjigaAdapter.KomentariViewHolder> {
private List<KnjigaModel> listaKnjiga;
private LayoutInflater inflater;
private Context context;
public KnjigaAdapter(Context context, List<KnjigaModel> listaKnjiga) {
this.listaKnjiga = listaKnjiga;
this.context = context;
}
#Override
public KomentariViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater = LayoutInflater.from(context);
// Inflate the custom layout
View postView = inflater.inflate(R.layout.single_item, parent, false);
// Return a new holder instance
return new KomentariViewHolder(postView);
}
#Override
public void onBindViewHolder(KomentariViewHolder holder, int position) {
KnjigaModel knjige = listaKnjiga.get(position);
holder.naslovKnjige.setText(knjige.getImeKnjige());
holder.imeAutora.setText(knjige.getImeAutora());
Glide.with(context)
.load(knjige.getSlikaKnjige())
.into(holder.slikaKnjige);
}
#Override
public int getItemCount() {
return listaKnjiga.size();
}
public class KomentariViewHolder extends RecyclerView.ViewHolder {
private TextView naslovKnjige;
private TextView imeAutora;
private ImageView slikaKnjige;
public KomentariViewHolder(View itemView) {
super(itemView);
naslovKnjige = itemView.findViewById(R.id.ime_knjige);
imeAutora = itemView.findViewById(R.id.autor_knjige);
slikaKnjige = itemView.findViewById(R.id.sika_korica);
}
}
}
my JSON format:
https://www.googleapis.com/books/v1/volumes?q=android
First of all, I strongly recommend to use RxJava for asynchronous requests, though it's totally optional.
Your Problem:
Your "getKnjige" Method returns only ONE Model, though the endpoint is named volumes (plural), you need to wrap your KnjigaModel in a class like
data class KnjigaResponse(val items: List<KnjigaModel>)
(Kotlin for simplicity, you can also generate a Java class with a single member volumes member that holds a list of KnjigaModel)
In addition, your model is wrong. authors is not a string, but a List of Strings, and "thumbnail" is wrapped in an "imageLinks" Object, and title is wrapped in a volumeInfo Object.
Your retrofit interface then would look like this:
public interface KnjigaApi {
#GET("v1/volumes")
Call<KnjigaResponse> getKnjige(#Query("q") String knjiga);
Request:
final Call<KnjigaResponse> pozivZaListuKnjiga = knjigaApi.getKnjige("android");
pozivZaListuKnjiga.enqueue(new Callback<KnjigaResponse>() {
#Override
public void onResponse(Call<KnjigaResponse> call, Response<KnjigaResponse> response) {
if (!response.isSuccessful()) {
return;
}
generateRecycleView(response.items);
}
#Override
public void onFailure(Call<KnjigaResponse> call, Throwable t) {
Log.d("MainActivity:", t.getMessage());
}
});
I am trying to retrieve Reddit information from a particular subreddit using Retrofit 2. I have followed many tutorials and videos and my code seems to be correct from my perspective but I only manage to have null objects in my model class. I have the permission for internet in the Manifest.
This is a link the JSON I am working with HERE
MainActivity
public class MainActivity extends AppCompatActivity
{
TextView mTextView;
Data mData;
private static final String TAG = "Battlestations";
#Override
protected void onCreate(Bundle savedInstanceState)
{
mTextView = (TextView) findViewById(R.id.test_view);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Call<Data> serviceCall = Service.getDesktopService().desks();
serviceCall.enqueue(new Callback<Data>()
{
#Override
public void onResponse(Call<Data> call, Response<Data> response)
{
Log.d("Reponce","return");
Log.i(TAG, "Response is " + mData.getChildren());
}
#Override
public void onFailure(Call<Data> call, Throwable t)
{
}
});
}
}
Api/Service Class
public class Service
{
private static final String BASE_URL = "https://www.reddit.com/r/";
private static DeskInterface mRetrofit;
public static DeskInterface getDesktopService()
{
if(mRetrofit == null)
{
Retrofit build = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
mRetrofit = build.create(DeskInterface.class);
}
return mRetrofit;
}
public interface DeskInterface
{
#GET("battlestations/hot/.json")
Call<Data> desks();
}
}
Data
public class Data
{
private List<Child> children = null;
public List<Child> getChildren()
{
return children;
}
public void setChildren(List<Child> children)
{
this.children = children;
}
}
Child
public class Child
{
private Data_ data;
public Data_ getData()
{
return data;
}
public void setData(Data_ data)
{
this.data = data;
}
}
Data_
public class Data_
{
private String subreddit;
private Integer score;
private String author;
private String subredditNamePrefixed;
private String url;
private String title;
public String getSubreddit()
{
return subreddit;
}
public void setSubreddit(String subreddit)
{
this.subreddit = subreddit;
}
public Integer getScore()
{
return score;
}
public void setScore(Integer score)
{
this.score = score;
}
public String getAuthor()
{
return author;
}
public void setAuthor(String author)
{
this.author = author;
}
public String getSubredditNamePrefixed()
{
return subredditNamePrefixed;
}
public void setSubredditNamePrefixed(String subredditNamePrefixed)
{
this.subredditNamePrefixed = subredditNamePrefixed;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
}
You need to add mData = response.body() in onResponse() (also check response.isSuccessful() first)
The problem is that your Data does not correspond with Reddit JSON. Your Data class
public class Data {
private List<Child> children = null;
}
does not match with the given json, which is:
{
"kind":"listing",
"data":{
"modhash":"...",
"children":[...],
"after":"...",
"before":"..."
}
}
Retrofit automagically convert from json to java but only if the mapping is correct.
A correct Java class would be:
public class Subreddit {
String kind;
Data data;
}
public class Data{
String modhash;
List<Child> children;
String after;
String before;
}
and then modify desks method interface to
Call<Subreddit> desks();
You would have to go recursively for the entire depth of the JSON to get the right mapping.
But before you get to work, just replace your Retrofit interface:
public interface DeskInterface{
#GET("battlestations/hot/.json")
Call<Data> desks();
}
with:
public interface DeskInterface{
#GET("battlestations/hot/.json")
Call<JsonObject> desks();
}
and it should return something. If is still null, then further investigation is needed. If it returns a valid response(some json text) then copy/paste that subreddit to this website where it converts all the json to a valid Java class
i tried retrofit with simple json response which have [ {},{},{},{},{},{},] array of objects which works but when i tried retrofit with status:
{"ok",count: 4,count_total: 4,pages: 1,posts: [{},{},{},{}] }
I came up with null results ..plz find the correct solution how do i Call the retrofit for correct result.
pojo class`
public class Categories {
#SerializedName("status")
private int status;
#SerializedName("id")
private int id;
#SerializedName("type")
private String type;
#SerializedName("title")
private String title;
#SerializedName("content")
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
mainactivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call<List<Categories>> call = apiService.response();
call.enqueue(new Callback<List<Categories>>() {
#Override
public void onResponse(Call<List<Categories>> call, Response<List<Categories>> response) {
List<Categories> movies = response.body();
recyclerView
.setAdapter(new MoviesAdapter(movies,
R.layout.list_item_movie, getApplicationContext()));
}
#Override
public void onFailure(Call<List<Categories>> call, Throwable t) {
}
});
}
apiclient.java
public class ApiClient {
public static final String BASE_URL = "http://androidaura.com/health/api/get_recent_posts/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
You should change your POJO to following:
Public class Model {
String status; // because "ok" is string not boolean
int count;
int count_total;
int pages;
List<Post> posts;
public class Post {
// add attribute of your old pojo
}
}
Also make sure your class attribute be same as Server response;
I am trying to use the google books API with Retrofit, it is returning an empty result.
this is the url:
https://www.googleapis.com/books/v1/volumes?q=9781451648546
In Retrofit I have an interface:
public interface IServiceEndPoint {
#GET("https://www.googleapis.com/books/v1/volumes?q=9781451648546")
Call<BookList> getBooks();
}
in my webservice class I have the following method:
public void getBooks(final Callback<BookList> callback){
IServiceEndPoint endPoint = mRetrofit.create(IServiceEndPoint.class);
Call<BookList> call = endPoint.getBooks();
call.enqueue(callback);
}
in the activity class I have the method:
private void getBooks(){
WebserviceHelper.getmInstance().getBooks(new Callback<BookList>() {
#Override
public void onResponse(Call<BookList> call, Response<BookList> response) {
mBooks = response.body().getResults();
mBookAdapter.update(mBooks);
}
#Override
public void onFailure(Call<BookList> call, Throwable t) {
}
});
}
I have a Java class Book and BookList.
public class Book implements Serializable {
#SerializedName("id")
private String id;
#SerializedName("title")
private String title;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
public class BookList extends Book implements Serializable {
#SerializedName("results")
private List<Book> results;
public List<Book> getResults() {
return results;
}
public void setResults(List<Book> results) {
this.results = results;
}
}
In the manifest file I added
uses-permission android:name="android.permission.INTERNET
mBooks is returning null value, how could I solve this?
Thank you.
EDIT: shuvro's answer helped me correcting the problem. I also forgot to include the volumeInfo in my Book class. My book class looks as followed now:
public class Book implements Serializable {
#SerializedName("id")
private String id;
private VolumeInfo volumeInfo;
public VolumeInfo getVolumeInfo() {
return volumeInfo;
}
public void setVolumeInfo(VolumeInfo volumeInfo) {
this.volumeInfo = volumeInfo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Additionally I created the class volumeInfo:
public class VolumeInfo {
private String title;
private String subtitle;
private String publisher;
private String description;
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Thanks all for the help!
Add the two dependency in your gradle file .
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Create a class , lets sats ServiceGenerator , your class should be like this
public class ServiceGenerator {
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl("https://www.googleapis.com/books/v1/")
.addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass) {
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
Now your declare your interface like this
public interface IServiceEndPoint {
#GET("volumes")
Call<BookList> getBooks(#Query("q") String id);
}
Now in activity or in fragment , use retrofit in this way
IServiceEndPoint serviceEndPoint = ServiceGenerator.createService(IServiceEndPoint.class)
Call<BookList> call = serviceEndPoint.getBooks("9781451648546");
call.enqueue(new Callback<BookList>() {
#Override
public void onResponse(Call<BookList> call, Response<BookList> response) {
//do whatever you want to do
}
#Override
public void onFailure(Call<BookList> call, Throwable t) {
}
});
You BookList POJO class has nothing to do with JSON response. It should be something like that:
public class BookList {
#SerializedName("items")
private List<Item> items = new ArrayList<Item>();
}
You can find all POJO classes for that response here.
I would go on this way and simply follow the way to do usually with retrofit.
public interface GBookService {
#GET("volumes?q=9781451648546")
Call<BookList> getBooks();
}
//
public class ApiHelper {
GBookService service;
public ApiHelper(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.googleapis.com/books/v1/")
.build();
service = retrofit.create(GBookService.class);
}
public GBookService getService(){
return service;
}
}
and where you want to use it :
Call<BookList> call = apiHelper.getService().getBooks();
call.enqueue(new Callback<BookList>() {
#Override
public void onResponse(Call<BookList> call, Response<BookList> response) {
}
#Override
public void onFailure(Call<BookList> call, Throwable t) {
}
});
And BookList, you got the idea I guess
public class BookList {
String kind;
int totalItems;
List<Book> items;
...
}
(off course adapt with your own code)
Also be sure to have added the internet permission.
You can follow this because there is no reasons to not success calling the api. just be sure also your field name are correct and match the one contained in the JSON returned.