JSON response Variable missing during compile time - android

I am setting up the recyclerview to show some data from the server and this is how my jsonpojo looks alike :
public class JSON {
public class MainCard {
#SerializedName("Cards")
public List<Cards> cards;
}
public class Cards {
#SerializedName("Title")
public String title;
#SerializedName("Items")
public List<ItemData> items;
}
public class ItemData {
#SerializedName("Name")
public String name;
#SerializedName("Thumb")
public String thumb;
#SerializedName("Link")
public String link;
}
}
and here is the adapter :
public class API_Adpater extends RecyclerView.Adapter<API_Adpater.CardsHolder> {
private List<JSON.ItemData> mlist;
private List<JSON.Cards> mCards;
private Context mcontext;
public API_Adpater(List<JSON.ItemData> mlists, List<JSON.Cards> titles, Context context) {
this.mlist = mlists;
this.mcontext = context;
this.mCards = titles;
}
#NonNull
#Override
public CardsHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.singleitems,viewGroup,false);
return new CardsHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CardsHolder cardsHolder, int i) {
final JSON.ItemData singleitem = mlist.get(i);
final JSON.Cards Title = mCards.get(i);
cardsHolder.textView.setText(Title.title);
cardsHolder.textView2.setText(singleitem.name);
cardsHolder.url = singleitem.thumb;
Glide.with(this.mcontext).load(cardsHolder.url).into(cardsHolder.imageView);
}
#Override
public int getItemCount() {
return mlist.size();
}
class CardsHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
TextView textView2;
String url;
CardsHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
textView = itemView.findViewById(R.id.textView);
textView2 = itemView.findViewById(R.id.textView2);
}
}
}
and this is the mainactivity :
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(APIService.url)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<JSON.MainCard> call = service.getCards();
call.enqueue(new Callback<JSON.MainCard>() {
#Override
public void onResponse(Call<JSON.MainCard> call, Response<JSON.MainCard> response) {
if (response.isSuccessful()) {
JSON.MainCard mainCard = response.body();
if (mainCard != null && mainCard.cards !=null) {
List<JSON.ItemData> ru = mainCard.cards.items;
// Here on Above Line it can't get the mainCard.Cards.items; it is not showing the `.items` in the code;
setupRV(ru);
}
} else {
Toast.makeText(MainActivity.this, "Reposnce Error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<JSON.MainCard> call, Throwable t) {
Toast.makeText(MainActivity.this, "Check Internet Connectivity", Toast.LENGTH_SHORT).show();
}
});
}
private void setupRV(List<JSON.ItemData> list) {
RecyclerView recyclerView = findViewById(R.id.rv);
LinearLayoutManager lm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(lm);
recyclerView.setAdapter(new API_Adpater(list,this));
}
}
On response of retrofit, I need to set the line like
List<JSON.ItemData> ru = mainCard.cards.items;
but it is not working as the codeeditor is not getting the .items variable
where is the error?
Can't set the recylcer view.
This is how my json looks alike :
{
"Cards": [
{
"Title": "Title",
"Items": [
{
"Name": "Name",
"Thumb": "Thumb",
"Link": "link"
}
]
},
{
"Title": "Title",
"Items": [
{
"Name": "Name",
"Thumb": "Thumb",
"Link": "link"
}
]
}
]
}
And this the error it can't find the items from the maincards.cards
I need to set the image from the url and name and title in the recycler view.

You're accessing items directly on list in this line
List<JSON.ItemData> ru = mainCard.cards.items;
here cards is a list, that's why you can't access items directly
Get the object of Cards and then use it
List<JSON.ItemData> ru = mainCard.cards.get(index).items;
Based on your requirements
you need to iterate over
if (mainCard != null && mainCard.cards !=null) {
List<JSON.ItemData> ru = new ArrayList();
for(Cards itemCard : mainCard.cards)
{
ru.addAll(itemCard.items);
}
setupRV(ru);
}

Try this..
List<MoviesApi.ItemData> ru = mainCard.cards.getItems();

Make separate class for each model as below.
-----------------------------------com.example.Card.java-----------------------------------
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Card {
#SerializedName("Title")
#Expose
public String title;
#SerializedName("Items")
#Expose
public List<Item> items = null;
}
-----------------------------------com.example.Item.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Item {
#SerializedName("Name")
#Expose
public String name;
#SerializedName("Thumb")
#Expose
public String thumb;
#SerializedName("Link")
#Expose
public String link;
}
-----------------------------------com.example.MainCard.java-----------------------------------
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class MainCard {
#SerializedName("Cards")
#Expose
public List<Card> cards = null;
}
To create these pojos I used this site http://www.jsonschema2pojo.org/

Related

Android: Fetch Different Object List Data Using Retrofit

I have am trying to fetch Different types of List data using Retrofit.
I have make a List and put data on that.
Can anyone suggest me how I can fetch Different Type of Model Data? I have When I tried to put Object List to my Custom model list I got this error :
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to .....
Model Class
public class WorkType {
#SerializedName("type")
#Expose
private String type;
#SerializedName("worklist")
#Expose
private List<Object> worklist = null;
/**
* No args constructor for use in serialization
*
*/
public WorkType() {
}
/**
*
* #param worklist
* #param type
*/
public WorkType(String type, List<Object> worklist) {
super();
this.type = type;
this.worklist = worklist;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Object> getWorkList() {
return worklist;
}
public void setWorkList(List<Object> worklist) {
this.worklist = worklist;
}
}
Retrofit Interface
#FormUrlEncoded
#POST("worklist")
Call<ArrayList<WorkType>> worklist(
#Field("teamid") String teamID
);
Fragment from where I make a API request
public class WorkTypeListFragment extends Fragment {
private FragmentWorkTypeListBinding binding;
private LoadingDialog loadingDialog;
private Context context;
public WorkTypeListFragment() {
// Required empty public constructor
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = DataBindingUtil.inflate(inflater,R.layout.fragment_work_type_list,container,false);
init();
String teamID = getActivity().getIntent().getStringExtra("teamid");
fetchClientDetails("team1");
return binding.getRoot();
}
private void init() {
loadingDialog = new LoadingDialog(getActivity());
}
private void fetchClientDetails(String teamID){
loadingDialog.startLoadingDialog(); // Added Loading Screen
Call<ArrayList<WorkType>> call = RetrofitClient
.getInstance()
.getRetrofitApi()
.worklist(teamID);
call.enqueue(new Callback<ArrayList<WorkType>>() {
#Override
public void onResponse(Call<ArrayList<WorkType>> call, Response<ArrayList<WorkType>> response) {
try{
if(response.code() == 200){
ArrayList<WorkType> workTypeArrayList = response.body();
//Log.d("TAG", "onResponse: "+workTypeArrayList.get(1).getWorkList().get(0).getClientname());
assert workTypeArrayList != null;
bindDataToView(workTypeArrayList);
} else {
Toast.makeText(getContext(), "Response Code is no 200", Toast.LENGTH_SHORT).show();
loadingDialog.dismissDialog();
}
}catch(Exception e){
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ArrayList<WorkType>> call, Throwable t) {
Toast.makeText(getContext(), "Something Went wrong! Please try again later!", Toast.LENGTH_SHORT).show();
loadingDialog.dismissDialog();
}
});
}
private void bindDataToView(ArrayList<WorkType> workTypeArrayList) {
WorkTypesAdapter adapter = new WorkTypesAdapter(context,workTypeArrayList);
binding.workTypeRv.setLayoutManager(new LinearLayoutManager(context));
binding.workTypeRv.setAdapter(adapter);
}
}
RecyclearView Adapter Class
public class WorkTypesAdapter extends RecyclerView.Adapter<WorkTypesAdapter.ViewHolder> {
private Context mCtx;
private List<WorkType> workTypeList;
private final static int survey = 1;
private final static int service = 2;
private final static int maintain = 3;
public WorkTypesAdapter(Context mCtx, List<WorkType> modelServiceList) {
this.mCtx = mCtx;
this.workTypeList = modelServiceList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.layout_worktype, null);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
WorkType currentWorkType = workTypeList.get(position);
String modelClass = currentWorkType.getType();
List<Object> objectList = currentWorkType.getWorkList();
switch (modelClass){
/*case "survey":
List<SurveyWorkList> surveyWorkLists = new ArrayList<>();
for (Object object : objectList) {
surveyWorkLists.add((SurveyWorkList) object);
holder.workType.setText(currentWorkType.getType());
holder.workTypeCount.setText(surveyWorkLists.size());
}
break;*/
case "service":
List<ServiceWorkList> serviceWorkLists = new ArrayList<>();
for (Object object : objectList) {
serviceWorkLists.add((ServiceWorkList) object);
}
/*holder.workType.setText(currentWorkType.getType());
holder.workTypeCount.setText(serviceWorkLists.size());*/
break;
/*case "maintain":
List<MaintainWorkList> maintainWorkLists = new ArrayList<>();
for (Object object : objectList) {
maintainWorkLists.add((MaintainWorkList) object);
}
holder.workType.setText(currentWorkType.getType());
holder.workTypeCount.setText(maintainWorkLists.size());
break;*/
default:
//Do nothing
}
/*holder.workType.setText(modelService.getType());
holder.workTypeCount.setText(workTypeList.size());*/
}
#Override
public int getItemCount() {
return workTypeList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView workType, workTypeCount;
public ViewHolder(#NonNull View itemView) {
super(itemView);
workType = itemView.findViewById(R.id.work_type_tv);
workTypeCount = itemView.findViewById(R.id.work_type_count_tv);
}
}
}
API response
[
{
"type": "survey",
"worklist": []
},
{
"type": "service",
"worklist": [
{
"serviceid": "HS2020031613054318",
"clientid": "R2020031612594874",
"clientname": "********",
"companyname": "",
"membership": "",
"phone": [
"*********"
],
"**************",
"account": 2,
"slot": "morning",
"orderstatus": "Completed",
"orderstatuscode": "8",
"remarks": ""
}
]
},
{
"type": "maintain",
"worklist": []
}
]
The survey and maintain will have different Parameter.
I have found the answer.
First, you have to make a model class:
#SerializedName("contents")
#Expose
private JsonElement contents = null;
In my API I got an element type. So you know in which type you have to parse the data. Let's say you have three types. So we will create a Type object:
switch(type)
case 1:
Type type = new TypeToken<ArrayList<Banner>>() {
}.getType();
ArrayList<Banner> bannerList = new Gson().fromJson(baseModel.getContents(), type);

Parse nested JSON values and display in recyclerview while sorting date wise

So I have to parse the following JSON and display the data in a two step recycler view, that is, at first screen the app should only display the Associate name and Amount,
But if I click over some list item, it should display the rest of the data too.
Also, I know that I would have to create a Model class for my response which implements the Comparable interface.
This class will override compareTo method which will gonna sort the transaction based on the transaction_date.
But I am at loss understanding the whole process because when I generate my POJO classes, I get four different java classes (Transaction, Datum , Card, Associate). And while I was creating the adapter for the recyclerview I was not able to access the "amount" field directly because it is present in another class.
{
"status": "success",
"status_code": "200",
"data": [
{
"transaction_id": "2",
"transaction_date": "2018-04-19 05:27:23.0",
"amount": "200.00",
"user_id": "2",
"currency": "MXN",
"associate_id": "1",
"associate": {
"is_active": "N",
"associate_type": "Autoservicio",
"name": "alsuper",
"created_date": "12-Feb-2018 07:31:58 AM",
"associate_id": "1",
"url": null,
"last_update_date": "12-Feb-2018 07:31:58 AM"
},
"card_id": "2",
"card": {
"bank_code": "002",
"is_active": "Y",
"allows_charges": "Y",
"card_number": "411111XXXXXX1111",
"openpay_card_id": "kiusphu8moqri6qys7sg",
"type": "debit",
"card_id": "2",
"expiration_year": "21",
"user_id": "2",
"expiration_month": "10",
"bank_name": "bank name",
"created_date": "21-Mar-2018 05:46:58 AM",
"brand": "visa",
"last_update_date": "21-Mar-2018 05:46:58 AM",
"holder_name": "name name name name"
}
}
]
}
I am happy to share the adapter classes, right now I didn't share is because I would like to get some fresh perspective over the problem.
Update 1
So after applying Raja Jawahar's solution i was able to run once, but after making the final changes, the following situation has arrived.
D/1: Loaded View
D/2: Loaded recycler View
I/art: Do partial code cache collection, code=22KB, data=30KB
After code cache collection, code=22KB, data=30KB
Increasing code cache capacity to 128KB
D/OkHttp: --> GET http://URL http/1.1
--> END GET
E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: (No such file or directory)
W/ImageView: resolveUri failed on bad bitmap uri:
D/OkHttp: <-- 200 http:URL (757ms)
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With
Content-Type: application/json
Content-Length: 4109
D/OkHttp: Date: Sun, 15 Jul 2018 13:42:20 GMT
D/OkHttp: {"status":"success","status_code":"200","data": DATA]}
<-- END HTTP (4109-byte body)
D/6: Passing to Adapter Failure
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
My supporting code is as follows,
Fragment
TransactionAssociate = new ArrayList<>();
recyclerView = (RecyclerView)view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
transactionsAdapter = new TransactionsAdapter(getContext(), TransactionAssociate);
recyclerView.setAdapter(transactionsAdapter);
Log.d("2", "Loaded recycler View");
APIInterface apiInterface = APIClient.getClient().create(APIInterface.class);
Call<List<Transactions>> call = apiInterface.getTransactionList(sharedPreferences.getString(UNIQUE_ID, "qwe"));
call.enqueue(new Callback<List<Transactions>>() {
#Override
public void onResponse(Call<List<Transactions>> call, Response<List<Transactions>> response) {
TransactionAssociate = response.body();
Log.d("5", "Passing to Adapter");
try {
transactionsAdapter.setTransactionsList(TransactionAssociate);
Log.d("4", "Passed to Adapter");
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public void onFailure(Call<List<Transactions>> call, Throwable t) {
Log.d("6", "Passing to Adapter Failure", t);
}
});
Http Interface
#GET("URL")
Call<List<Transactions>>getTransactionList(#Path(value = "user_id",encoded = true)String user_id);
Adapter
public class TransactionsAdapter extends RecyclerView.Adapter<TransactionsAdapter.MyViewHolder>{
private Context context;
private List <Transactions> TransactionsList;
public TransactionsAdapter(Context context, List<Transactions> TransactionsList) {
this.context = context;
this.TransactionsList = TransactionsList;
}
public void setTransactionsList(List<Transactions> transactionsList){
this.TransactionsList = transactionsList;
notifyDataSetChanged();
}
#Override
public TransactionsAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
}
#Override
public void onBindViewHolder(TransactionsAdapter.MyViewHolder holder, int position) {
Transactions transactionsList = TransactionsList.get(position);
Transactions.DataEntity dataEntity = transactionsList.getData().get(0);
holder.associateName.setText(dataEntity.getAssociate().getName());
}
#Override
public int getItemCount() {
return 0;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(View itemView) {
super(itemView);
}
}
}
Transactions.class
public class Transactions {
#SerializedName("data")
private List<DataEntity> data;
#SerializedName("status_code")
private String statusCode;
#SerializedName("status")
private String status;
public List<DataEntity> getData() {
return data;
}
public void setData(List<DataEntity> data) {
this.data = data;
}
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public static class DataEntity {
#SerializedName("card")
private CardEntity card;
#SerializedName("card_id")
private String cardId;
#SerializedName("associate")
private AssociateEntity associate;
#SerializedName("associate_id")
private String associateId;
#SerializedName("currency")
private String currency;
#SerializedName("user_id")
private String userId;
#SerializedName("amount")
private String amount;
#SerializedName("transaction_date")
private String transactionDate;
#SerializedName("transaction_id")
private String transactionId;
}
public static class CardEntity {
#SerializedName("holder_name")
private String holderName;
#SerializedName("last_update_date")
private String lastUpdateDate;
#SerializedName("brand")
private String brand;
#SerializedName("created_date")
private String createdDate;
#SerializedName("bank_name")
private String bankName;
#SerializedName("expiration_month")
private String expirationMonth;
#SerializedName("user_id")
private String userId;
#SerializedName("expiration_year")
private String expirationYear;
#SerializedName("card_id")
private String cardId;
#SerializedName("type")
private String type;
#SerializedName("openpay_card_id")
private String openpayCardId;
#SerializedName("card_number")
private String cardNumber;
#SerializedName("allows_charges")
private String allowsCharges;
#SerializedName("is_active")
private String isActive;
#SerializedName("bank_code")
private String bankCode;
}
public static class AssociateEntity {
#SerializedName("last_update_date")
private String lastUpdateDate;
#SerializedName("associate_id")
private String associateId;
#SerializedName("created_date")
private String createdDate;
#SerializedName("name")
private String name;
#SerializedName("associate_type")
private String associateType;
#SerializedName("is_active")
private String isActive;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
Use DTO Generator(Android Plugin to create a Model Class)
Create a class like below for your Response
public class DataModel {
#SerializedName("data") private List<Data> data; #SerializedName("status_code") private String status_code; #SerializedName("status") private String status;
public static class Data {
#SerializedName("card")
private Card card;
#SerializedName("card_id")
private String card_id;
#SerializedName("associate")
private Associate associate;
#SerializedName("associate_id")
private String associate_id;
#SerializedName("currency")
private String currency;
#SerializedName("user_id")
private String user_id;
#SerializedName("amount")
private String amount;
#SerializedName("transaction_date")
private String transaction_date;
#SerializedName("transaction_id")
private String transaction_id; }
public static class Card {
#SerializedName("holder_name")
private String holder_name;
#SerializedName("last_update_date")
private String last_update_date;
#SerializedName("brand")
private String brand;
#SerializedName("created_date")
private String created_date;
#SerializedName("bank_name")
private String bank_name;
#SerializedName("expiration_month")
private String expiration_month;
#SerializedName("user_id")
private String user_id;
#SerializedName("expiration_year")
private String expiration_year;
#SerializedName("card_id")
private String card_id;
#SerializedName("type")
private String type;
#SerializedName("openpay_card_id")
private String openpay_card_id;
#SerializedName("card_number")
private String card_number;
#SerializedName("allows_charges")
private String allows_charges;
#SerializedName("is_active")
private String is_active;
#SerializedName("bank_code")
private String bank_code; }
public static class Associate {
#SerializedName("last_update_date")
private String last_update_date;
#SerializedName("associate_id")
private String associate_id;
#SerializedName("created_date")
private String created_date;
#SerializedName("name")
private String name;
#SerializedName("associate_type")
private String associate_type;
#SerializedName("is_active")
private String is_active; } }
Access your DataModel in your Adapter like below
package com.mobieadz.sales;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public class MyRecylerViewAdapter extends RecyclerView.Adapter<MyRecylerViewAdapter.MyViewHolder> {
private Context context;
private List<Data> datas = new ArrayList<>();
#NonNull #Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent,
int viewType) {
return null;
}
public MyRecylerViewAdapter(Context context, List<DataModel> dataModels) {
this.context = context;
this.dataModels = dataModels;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Data data = datas.get(position);
youtextView.setText(data.amount);
yourtextView.setText(data.associate.name)
yourtextView.setText(data.associate.name)
}
#Override public int getItemCount() {
return dataModels.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
super(itemView);
}
}
}

How to use Nested RecyclerView to get intended design

I'm having JSON format as below, I'm able to fetch this JSON data into android using retrofit but after fetching I'm not getting how to display it in Horizontal RecyclerView in Vertical RecyclerView as shown in below image, I want AAAAA to be displayed instead of Section1 and name1 instead of item1 and respective image to be displayed. Please help me to write android code for this.
{"result":
{"AAAAA":[{"firm_name":"name1","image_path":"1.jpg"},
{"firm_name":"name2","image_path":"2.jpg"}],
"BBBBB":[{"firm_name":"name1","image_path":"1.jpg"}],
"CCCCC":[{"firm_name":"name1","image_path":"1.jpg"}],
"DDDDD":[{"firm_name":"name1","image_path":"1.jpg"}],
"EEEEE":[{"firm_name":"name1","image_path":"1.jpg"}]
}
}
This is my Json code
Here is my pojo class
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("result")
#Expose
private Result result;
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
}
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Result {
#SerializedName("AAAAA")
#Expose
private List<AAAAA> aAAAA = null;
#SerializedName("BBBBB")
#Expose
private List<BBBBB> bBBBB = null;
#SerializedName("CCCCC")
#Expose
private List<Object> cCCCC = null;
#SerializedName("DDDDD")
#Expose
private List<Object> dDDDD = null;
#SerializedName("EEEEE")
#Expose
private List<Object> eEEEE = null;
public List<AAAAA> getAAAAA() {
return aAAAA;
}
public void setAAAAA(List<AAAAA> aAAAA) {
this.aAAAA = aAAAA;
}
public List<BBBBB> getBBBBB() {
return bBBBB;
}
public void setBBBBB(List<BBBBB> bBBBB) {
this.bBBBB = bBBBB;
}
public List<Object> getCCCCC() {
return cCCCC;
}
public void setCCCCC(List<Object> cCCCC) {
this.cCCCC = cCCCC;
}
public List<Object> getDDDDD() {
return dDDDD;
}
public void setDDDDD(List<Object> dDDDD) {
this.dDDDD = dDDDD;
}
public List<Object> getEEEEE() {
return eEEEE;
}
public void setEEEEE(List<Object> eEEEE) {
this.eEEEE = eEEEE;
}
}

Make a Recyclerview Android from API but, it doesn't work

I've been working with Recycler view Android. I try to make a Recycler view from API Response. But, the list didn't show up, my adapter was not working. When i tried to debug this program, I got List<Produclist> list is null.
This my JSON Response from API
{
"code": 0,
"data": [
{
"product_list": [
{
"return_level": 0,
"image": "ee0c97c5-1752-4f1a-b713-2308eb1284d8",
"risk_level": "Aggresive",
"code": "P0011",
"price": {
"date": null,
"value": 0
},
"name": "Dana Ekuitas Prima"
},
{
"return_level": 0,
"image": "ee0c97c5-1752-4f1a-b713-2308eb1284d8",
"risk_level": "Aggresive",
"code": "P0001",
"price": {
"date": "2017-01-03T11:44:52.6152Z",
"value": 150000
},
"name": "Manulife Dana Saham"
},
{
"return_level": 0,
"image": "ee0c97c5-1752-4f1a-b713-2308eb1284d8",
"risk_level": "Aggresive",
"code": "P0008",
"price": {
"date": null,
"value": 0
},
"name": "Trim Kapital Plus"
},
{
"return_level": 0,
"image": "ee0c97c5-1752-4f1a-b713-2308eb1284d8",
"risk_level": "Aggresive",
"code": "P0004",
"price": {
"date": "2017-01-03T11:44:52.6152Z",
"value": 150000
},
"name": "Manulife Syariah Sektoral Amanah"
}
],
"type": "Reksa Dana Saham"
}
],
"info": "Product list successfully loaded"
}
This My setter getter
public class ProductListResponse {
#SerializedName("code")
#Expose
private Integer code;
#SerializedName("info")
#Expose
private String info;
#SerializedName("data")
#Expose
private List<CategoryType> listCategory = new ArrayList<>();
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public List<CategoryType> getListCategory() {
return listCategory;
}
public void setListCategory(List<CategoryType> listCategory) {
this.listCategory = listCategory;
}
}
Setter getter of category type
public class CategoryType {
#SerializedName("type")
#Expose
private String type;
#SerializedName("product_list")
#Expose
private List<ProductList> productList = new ArrayList<ProductList>();
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<ProductList> getProductList() {
return productList;
}
public void setProductList(List<ProductList> productList) {
this.productList = productList;
}
}
Setter getter of ProductList
public class ProductList implements Serializable {
#SerializedName("code")
#Expose
private String code;
#SerializedName("name")
#Expose
private String name;
#SerializedName("price")
#Expose
private Price price;
#SerializedName("risk_level")
#Expose
private String riskLevel;
#SerializedName("return_level")
#Expose
private Double returnLevel;
#SerializedName("image")
#Expose
private String image;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getRiskLevel() {
return riskLevel;
}
public void setRiskLevel(String riskLevel) {
this.riskLevel = riskLevel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Price getPrice() {
return price;
}
public void setPrice(Price price) {
this.price = price;
}
public Double getreturnLevel() {
return returnLevel;
}
public void setReturnLevel(Double returnLevel) {
this.returnLevel = returnLevel;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
This my Activity
public class ProductActivity extends AppCompatActivity {
private RecyclerView rvView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
public List<ProductList> list;
Context context;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.f_list_of_product);
request(constructSignUpRequest());
rvView = (RecyclerView) findViewById(R.id.rv);
rvView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
rvView.setLayoutManager(layoutManager);
adapter = new ProductAdapter(context, list);
rvView.setAdapter(adapter);
}
public BTNService.Api getApi() {
return getBTNService().getApi();
}
public BTNService getBTNService() {
return new BTNService(this);
}
void request(final ProductListRequest productListRequest) {
getApi().loadproductlist(productListRequest.getCode())
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Observer<ProductListResponse>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
Timber.e(e.getLocalizedMessage());
}
#Override
public void onNext(ProductListResponse response) {
if (response != null) {
Intent intent = new Intent(ProductActivity.this, ProductList.class);
startActivity(intent);
}
}
});
}
public ProductListRequest constructSignUpRequest() {
ProductListRequest request = new ProductListRequest();
request.setCode(Category);
return request;
}
}
This my Adapter
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.CatalogueHolder> {
private Context context;
private List<ProductList> list;
public ProductAdapter(Context context, List<ProductList> list) {
this.context = context;
this.list = list;
}
#Override
public CatalogueHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_product, parent, false);
CatalogueHolder catalogueHolder = new CatalogueHolder(itemView);
return catalogueHolder;
}
#Override
public void onBindViewHolder(CatalogueHolder holder, int position) {
final ProductList item = list.get(position);
holder.itemView.setTag(item);
holder.productName.setText(item.getName());
}
#Override
public int getItemCount() {
return list != null ? list.size() : 0;
}
public static class CatalogueHolder extends RecyclerView.ViewHolder {
#Bind(R.id.productname)
TextView productName;
#Bind(R.id.typeProduct)
TextView typeProduct;
#Bind(R.id.price)
TextView price;
#Bind(R.id.date)
TextView date;
public CatalogueHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
Sorry, if it's quite long. I have to show all my code to make it clear. I really need your help guys. Thanks
Set adapter inside onComplete method:
void request(final ProductListRequest productListRequest) {
getApi().loadproductlist(productListRequest.getCode())
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Observer<ProductListResponse>() {
#Override
public void onCompleted() {
rvView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
rvView.setLayoutManager(layoutManager);
adapter = new ProductAdapter(context, list);
rvView.setAdapter(adapter);
}
#Override
public void onError(Throwable e) {
Timber.e(e.getLocalizedMessage());
}
#Override
public void onNext(ProductListResponse response) {
if (response != null) {
Intent intent = new Intent(ProductActivity.this, ProductList.class);
startActivity(intent);
}
}
});
}

Expected STRING but was BEGIN_ARRAY, Realm and JSON

I have write JSON file:
[
{ "name" : "Sir",
"votes" : 23,
"imageURL" : "http://img.prntscr.com/img?url=http://i.imgur.com/5ogv5yJ.png" },
{ "name" : "Bar",
"votes" : 21,
"imageURL" : [
"http://img.prntscr.com/img?url=http://i.imgur.com/G1qQb9Q.png",
"http://www.dreamhost.com/blog/wp-content/uploads/2015/10/DHC_blog-image-01-300x300.jpg",
"http://lh5.ggpht.com/yt6SnO_2jOIot1FhQYGiVXd_IQWBOCmQ1UJBddyau3Wzw1ZgpdeQwpO7TRFnux3Dirk=w300",
"http://i.vimeocdn.com/portrait/4728693_300x300.jpg",
"http://www.raspberrypi.org/wp-content/themes/mind-control/images/octocat.jpg"
]
},
{ "name" : "Buildings",
"votes" : 19,
"imageURL" : "http://img.prntscr.com/img?url=http://i.imgur.com/brzudoL.png"}
]
Model class
public class City extends RealmObject {
private String name;
private long votes;
private String imageURL;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVotes() {
return votes;
}
public void setVotes(long votes) {
this.votes = votes;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
}
And Adapter
public class CityAdapter extends BaseAdapter {
//private final Context context;
private LayoutInflater inflater;
private List<City> cities = null;
/* public CityAdapter(Context context) {
this.context = context; */
public CityAdapter(Context context) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setData(List<City> details) {
this.cities = details;
}
#Override
public int getCount() {
if (cities == null) {
return 0;
}
return cities.size();
}
#Override
public Object getItem(int position) {
if (cities == null || cities.get(position) == null) {
return null;
}
return cities.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View currentView, ViewGroup parent) {
if (currentView == null) {
currentView = inflater.inflate(R.layout.city_listitem, parent, false);
}
City city = cities.get(position);
ImageView photo = (ImageView) currentView.findViewById(R.id.picture);
if (city != null) {
Picasso.with(inflater.getContext()).load(city.getImageURL()).placeholder(R.drawable.internet_access_placeholder).into(photo);
((TextView) currentView.findViewById(R.id.name)).setText(city.getName());
((TextView) currentView.findViewById(R.id.votes)).setText(String.format(Locale.US, "%d", city.getVotes()));
}
return currentView;
}
}
down there in adapter I setup picasso:
Picasso.with(inflater.getContext()).load(city.getImageURL()).placeholder(R.drawable.internet_access_placeholder).into(photo);
And project is working when I got only one photo in JSON like image from object "name" : "Sir"
But When I write multiple URLs like in 2nd object "name" : "Bar" I get that error: "Expected STRING but was BEGIN_ARRAY"
I understand what is problem but I don't know how to fix it...
I want to have more than one photo in some objects like in 2nd
then always expect / send an array and map it to a list and check for the list size
final List<String> urls = city.getImageURLs();
if (urls.size() > 1) {
// add code for more images
} else {
Picasso.with(inflater.getContext()).load(urls.get(0)).placeholder(R.drawable.internet_access_placeholder).into(photo);
}
imageURL must be Json array
[
{ "name" : "Sir",
"votes" : 23,
"imageURL" : [ "http://img.prntscr.com/img?url=http://i.imgur.com/5ogv5yJ.png" ] },
{ "name" : "Bar",
"votes" : 21,
"imageURL" : [
"http://img.prntscr.com/img?url=http://i.imgur.com/G1qQb9Q.png",
"http://www.dreamhost.com/blog/wp-content/uploads/2015/10/DHC_blog-image-01-300x300.jpg",
"http://lh5.ggpht.com/yt6SnO_2jOIot1FhQYGiVXd_IQWBOCmQ1UJBddyau3Wzw1ZgpdeQwpO7TRFnux3Dirk=w300",
"http://i.vimeocdn.com/portrait/4728693_300x300.jpg",
"http://www.raspberrypi.org/wp-content/themes/mind-control/images/octocat.jpg"
]
}
]
and your model must be like that
public class City extends RealmObject {
private String name;
private long votes;
private List<String> imageURL;
.
.
.
}

Categories

Resources