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

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);
}
}
});
}

Related

I'm stuck somewhere in between getting json array inside a object setting to recview, I have to send a key to fetch data in. Didn't get solutions here

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
}
]
}

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 1 error

I'm new to android programming. I have a class where retrofit API call is done to parse and display few attributes JSON file. But I get:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
at line 2 column 1
Kindly help. I searched for answers but I couldn't find anything wrong with the JSON response. Posted my JSON response and JAVA class:
JSON Response:
{
"status": 1,
"active_requests": [
{
"id": "12",
"driver_id": "2",
"booking_id": "12",
"request_status": "1",
"created_on": "2018-09-13 19:57:29",
"updated_on": "2018-09-13 19:57:29",
"customer_id": "1",
"pickup_location": "GN Mills",
"drop_location": "Vadavalli",
"pickup_latitude": "11.025625",
"pickup_longitude": "76.955467",
"drop_latitude": "18.5645654",
"drop_longitude": "17.5645654",
"pickup_date_time": "2018-09-28 15:25:00",
"drop_date_time": "2018-09-28 15:25:00",
"package_weight": "55.5",
"package_type": "1",
"package_description": "fdasd dsaD YDASYD",
"vechicle_type": "car",
"service_status": "1",
"total_distance": "0",
"service_fare": "3460.6110936131",
"driver_fare": "2768.4888748905",
"paid_amount": "0",
"card_id": "0",
"picked_time": "0000-00-00 00:00:00",
"dropped_time": "0000-00-00 00:00:00"
}
]
}
JAVA File:
public class DriverDashboardFragment extends Fragment {
View root_view;
#BindView(R.id.linear_detail)
LinearLayout linearDetail;
#BindView(R.id.img_back)
ImageView imgBack;
#BindView(R.id.txt_title)
TextView txt_title;
SharedPreferences sharedPreferences;
Unbinder unbinder;
Context context;
RecyclerView recyclerView;
DriverDashboardAdapter driverDashboardAdapter;
List<DriverRequestModel> driver_list;
String id;
public static DriverDashboardFragment newInstance() {
DriverDashboardFragment fragment = new DriverDashboardFragment();
return fragment;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
root_view = inflater.inflate(R.layout.driverfragment_dashboard, container, false);
unbinder = ButterKnife.bind(this, root_view);
context = getContext();
sharedPreferences = getActivity().getSharedPreferences("MyPref", 0); // 0 - for private mode
id = PrefConnect.readString(getActivity(), PrefConnect.CUSTOMER_ID, "");
String msg= sharedPreferences.getString("message","");
Log.i("TAG",msg);
txt_title.setText("Dashboard");
imgBack.setVisibility(View.GONE);
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
ApiService apiService = (ApiService) RetrofitSingleton.getApiService();
Call<DriverRequestModel> call = apiService.getdriverrequest();
call.enqueue(new Callback<DriverRequestModel>() {
#Override
public void onResponse(Call<DriverRequestModel> call, Response<DriverRequestModel> response) {
driver_list = new ArrayList<>();
DriverRequestModel promo=response.body();
driver_list = promo.getActiveRequests();
Log.e("Response = ",new Gson().toJson(response.body()));
PrefConnect.writeString(context,PrefConnect.CUSTOMER_ID,response.body().getCustomerId()+"");
recyclerView = (RecyclerView)root_view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
driverDashboardAdapter = new DriverDashboardAdapter(getContext(),driver_list);
recyclerView.setAdapter(driverDashboardAdapter);
}
#Override
public void onFailure(Call<DriverRequestModel> call, Throwable t) {
Log.e("TAG","Response = "+t.toString());
}
});
return root_view;
}
#OnClick({R.id.linear_detail})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.linear_detail:
Intent detail = new Intent(context, DriverServiceDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putInt("key_1", 1);
detail.putExtras(bundle);
startActivity(detail);
break;
}
}
}
Model Class:
public class DriverRequestModel {
#SerializedName("status")
#Expose
public Integer status;
#SerializedName("active_requests")
#Expose
public List<ActiveRequest> activeRequests = null;
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public List<ActiveRequest> getActiveRequests() {
return activeRequests;
}
public void setActiveRequests(List<ActiveRequest> activeRequests) {
this.activeRequests = activeRequests;
}
public class ActiveRequest {
#SerializedName("id")
#Expose
public String id;
#SerializedName("driver_id")
#Expose
public String driverId;
#SerializedName("booking_id")
#Expose
public String bookingId;
#SerializedName("request_status")
#Expose
public String requestStatus;
#SerializedName("created_on")
#Expose
public String createdOn;
#SerializedName("updated_on")
#Expose
public String updatedOn;
#SerializedName("customer_id")
#Expose
public String customerId;
#SerializedName("pickup_location")
#Expose
public String pickupLocation;
#SerializedName("drop_location")
#Expose
public String dropLocation;
#SerializedName("pickup_latitude")
#Expose
public String pickupLatitude;
#SerializedName("pickup_longitude")
#Expose
public String pickupLongitude;
#SerializedName("drop_latitude")
#Expose
public String dropLatitude;
#SerializedName("drop_longitude")
#Expose
public String dropLongitude;
#SerializedName("pickup_date_time")
#Expose
public String pickupDateTime;
#SerializedName("drop_date_time")
#Expose
public String dropDateTime;
#SerializedName("package_weight")
#Expose
public String packageWeight;
#SerializedName("package_type")
#Expose
public String packageType;
#SerializedName("package_description")
#Expose
public String packageDescription;
#SerializedName("vechicle_type")
#Expose
public String vechicleType;
#SerializedName("service_status")
#Expose
public String serviceStatus;
#SerializedName("total_distance")
#Expose
public String totalDistance;
#SerializedName("service_fare")
#Expose
public String serviceFare;
#SerializedName("driver_fare")
#Expose
public String driverFare;
#SerializedName("paid_amount")
#Expose
public String paidAmount;
#SerializedName("card_id")
#Expose
public String cardId;
#SerializedName("picked_time")
#Expose
public String pickedTime;
#SerializedName("dropped_time")
#Expose
public String droppedTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDriverId() {
return driverId;
}
public void setDriverId(String driverId) {
this.driverId = driverId;
}
public String getBookingId() {
return bookingId;
}
public void setBookingId(String bookingId) {
this.bookingId = bookingId;
}
public String getRequestStatus() {
return requestStatus;
}
public void setRequestStatus(String requestStatus) {
this.requestStatus = requestStatus;
}
public String getCreatedOn() {
return createdOn;
}
public void setCreatedOn(String createdOn) {
this.createdOn = createdOn;
}
public String getUpdatedOn() {
return updatedOn;
}
public void setUpdatedOn(String updatedOn) {
this.updatedOn = updatedOn;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getPickupLocation() {
return pickupLocation;
}
public void setPickupLocation(String pickupLocation) {
this.pickupLocation = pickupLocation;
}
public String getDropLocation() {
return dropLocation;
}
public void setDropLocation(String dropLocation) {
this.dropLocation = dropLocation;
}
public String getPickupLatitude() {
return pickupLatitude;
}
public void setPickupLatitude(String pickupLatitude) {
this.pickupLatitude = pickupLatitude;
}
public String getPickupLongitude() {
return pickupLongitude;
}
public void setPickupLongitude(String pickupLongitude) {
this.pickupLongitude = pickupLongitude;
}
public String getDropLatitude() {
return dropLatitude;
}
public void setDropLatitude(String dropLatitude) {
this.dropLatitude = dropLatitude;
}
public String getDropLongitude() {
return dropLongitude;
}
public void setDropLongitude(String dropLongitude) {
this.dropLongitude = dropLongitude;
}
public String getPickupDateTime() {
return pickupDateTime;
}
public void setPickupDateTime(String pickupDateTime) {
this.pickupDateTime = pickupDateTime;
}
public String getDropDateTime() {
return dropDateTime;
}
public void setDropDateTime(String dropDateTime) {
this.dropDateTime = dropDateTime;
}
public String getPackageWeight() {
return packageWeight;
}
public void setPackageWeight(String packageWeight) {
this.packageWeight = packageWeight;
}
public String getPackageType() {
return packageType;
}
public void setPackageType(String packageType) {
this.packageType = packageType;
}
public String getPackageDescription() {
return packageDescription;
}
public void setPackageDescription(String packageDescription) {
this.packageDescription = packageDescription;
}
public String getVechicleType() {
return vechicleType;
}
public void setVechicleType(String vechicleType) {
this.vechicleType = vechicleType;
}
public String getServiceStatus() {
return serviceStatus;
}
public void setServiceStatus(String serviceStatus) {
this.serviceStatus = serviceStatus;
}
public String getTotalDistance() {
return totalDistance;
}
public void setTotalDistance(String totalDistance) {
this.totalDistance = totalDistance;
}
public String getServiceFare() {
return serviceFare;
}
public void setServiceFare(String serviceFare) {
this.serviceFare = serviceFare;
}
public String getDriverFare() {
return driverFare;
}
public void setDriverFare(String driverFare) {
this.driverFare = driverFare;
}
public String getPaidAmount() {
return paidAmount;
}
public void setPaidAmount(String paidAmount) {
this.paidAmount = paidAmount;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getPickedTime() {
return pickedTime;
}
public void setPickedTime(String pickedTime) {
this.pickedTime = pickedTime;
}
public String getDroppedTime() {
return droppedTime;
}
public void setDroppedTime(String droppedTime) {
this.droppedTime = droppedTime;
}
}
}
Are you using the right model for mapping your response? Should it be:
DriverRequestModel driverRequestModel = response.body();

Server Data is not fetching in Retrofit

I want to fetch some data from the server by using the retrofitlibrary on RecyclerView but the data is not showing on RecycleView. I read lots of answers but did not solve it yet so please solve my problem thank you in advance.
Below is my JSON Data
{
"item": [
{
"Item_Id": "1",
"Item_Name": "Item Name 1",
"Item_Description": "Item Name 1 Description",
"Item_Price": "330.00",
"Discount": "10",
"Item_Image": "http://192.168.1.5/easyshop/Items_Image/xyz.jpg",
"First_Name": "abc",
"Last_Name": "xyz",
"Mobile": "**********"
},
{
"Item_Id": "2",
"Item_Name": "Item Name 2",
"Item_Description": "Item Name 2 Description",
"Item_Price": "40.00",
"Discount": "30",
"Item_Image": "http://192.168.1.5/easyshop/Items_Image/xyz1.jpg",
"First_Name": "def",
"Last_Name": "uvw",
"Mobile": "**********"
}
]
}
API Client class where I have used the base URL, GSON and retrofit object
public class ApiClient {
public static final String BASE_URL = "http://192.168.1.5/easyshop/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(100, TimeUnit.SECONDS)
.readTimeout(100,TimeUnit.SECONDS)
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
Interface
public interface APIService {
#FormUrlEncoded
#POST("GetItem.php")
Call<ItemArray> getItem(#Field("Retailer_Id")int Retailer_Id);
}
When I put JSON data in www.jsonschema2pojo.org it generates two files which are following as below
public class ItemArray {
#SerializedName("item")
#Expose
private List<ItemList> item = null;
public List<ItemList> getItem() {
return item;
}
public void setItem(List<ItemList> item) {
this.item = item;
}
}
getter Setter Class
public class ItemList {
#SerializedName("Item_Id")
#Expose
private String itemId;
#SerializedName("Item_Name")
#Expose
private String itemName;
#SerializedName("Item_Description")
#Expose
private String itemDescription;
#SerializedName("Item_Price")
#Expose
private String itemPrice;
#SerializedName("Discount")
#Expose
private String discount;
#SerializedName("Item_Image")
#Expose
private String itemImage;
#SerializedName("First_Name")
#Expose
private String firstName;
#SerializedName("Last_Name")
#Expose
private String lastName;
#SerializedName("Mobile")
#Expose
private String mobile;
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemDescription() {
return itemDescription;
}
public void setItemDescription(String itemDescription) { this.itemDescription = itemDescription; }
public String getItemPrice() {
return itemPrice;
}
public void setItemPrice(String itemPrice) {
this.itemPrice = itemPrice;
}
public String getDiscount() {
return discount;
}
public void setDiscount(String discount) {
this.discount = discount;
}
public String getItemImage() {
return itemImage;
}
public void setItemImage(String itemImage) {
this.itemImage = itemImage;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
Adapter Class
public class Item_Card_Adapter extends RecyclerView.Adapter<Item_Card_Adapter.ViewHolder> {
//List to store all items
List<ItemList> items;
//Constructor of this class
public Item_Card_Adapter(List<ItemList> items){
super();
//Getting all items
this.items = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_layout,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(Item_Card_Adapter.ViewHolder holder, int position) {
holder.itemName.setText(items.get(position).getItemName());
holder.itemDesc.setText(items.get(position).getItemDescription());
holder.itemPrice.setText(items.get(position).getItemPrice());
}
#Override
public int getItemCount() {return items.size();}
class ViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.ItemName) TextView itemName;
#Bind(R.id.ItemDesc) TextView itemDesc;
#Bind(R.id.ItemPrice) TextView itemPrice;
#Bind(R.id.cardView) CardView cardView;
//Initializing Views
public ViewHolder(final View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
Item_Get_Activity Activity class
public class Item_Get_Activity extends AppCompatActivity {
#Bind(R.id.recyclerrView) RecyclerView recyclerView;
#Bind(R.id.progressBar) ProgressBar progressBar;
private List<ItemList> data;
private Item_Card_Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.item_get_activity);
ButterKnife.bind(this);
initViews();
}
private void initViews() {
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
getDataFromServer();
}
public void getDataFromServer() {
int i = 1;
APIService service = ApiClient.getClient().create(APIService.class);
Call<ItemArray> userCall = service.getItem(i);
userCall.enqueue(new Callback<ItemArray>() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onResponse(Call<ItemArray> call, Response<ItemArray> response) {
if(response.isSuccessful()){
progressBar.setVisibility(View.GONE);
data = response.body().getItem();
adapter = new Item_Card_Adapter(data);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onFailure(Call<ItemArray> call, Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
}
You need to change your ApiServices Interface like this
public interface APIService {
#FormUrlEncoded
#POST("GetItem.php")
Call<ItemArray> getItem(#Field("Retailer_Id")int Retailer_Id);
}
Then in your Activity update the calling method
public void getDataFromServer() {
int i = 1;
APIService service = ApiClient.getClient().create(APIService.class);
Call<ItemArray> userCall = service.getItem(i);
userCall.enqueue(new Callback<ItemArray>() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onResponse(Call<ItemArray> call, Response<ItemArray> response) {
if(response.isSuccessful()){
progressBar.setVisibility(View.GONE);
data = response.body().getItem();
adapter = new Item_Card_Adapter(data);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onFailure(Call<List<ItemList>> call, Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
Since your api response contain the "list" inside a Json object. You need a class that has a List variable. So retrofit will parse the response to ItemArray successfully
Update
The demo code link https://github.com/Siddharth-Dev/RetrofitDemo
This has your code and a working API code too.

Resources$NotFoundException When calling a Rest API using RetroFit 2

I am calling a REST Api with RetroFit 2 and trying to display it with a RecyclerView but for some reason I am getting a Resources$NotFoundException.
The JSON generated That i want to read and display in a RecyclerView is:
{
"generated_at": "2018-05-31T12:10:29+00:00",
"schema": "http:\/\/schemas.sportradar.com\/bsa\/soccer\/v1\/json\/endpoints\/soccer\/tournament_standings.json",
"tournament": {
"id": "sr:tournament:17",
"name": "Premier League",
"sport": {
"id": "sr:sport:1",
"name": "Soccer"
},
"category": {
"id": "sr:category:1",
"name": "England",
"country_code": "ENG"
},
"current_season": {
"id": "sr:season:40942",
"name": "Premier League 17\/18",
"start_date": "2017-08-11",
"end_date": "2018-05-14",
"year": "17\/18"
}
},
"season": {
"id": "sr:season:40942",
"name": "Premier League 17\/18",
"start_date": "2017-08-11",
"end_date": "2018-05-14",
"year": "17\/18",
"tournament_id": "sr:tournament:17"
},
"standings": [{
"tie_break_rule": "In the event that two (or more) teams have an equal number of points, the following rules break the tie:\r\n1. Goal difference\r\n2. Goals scored",
"type": "total",
"groups": [{
"team_standings": [{
"team": {
"id": "sr:competitor:17",
"name": "Manchester City"
},
"rank": 1,
"current_outcome": "Champions League",
"played": 38,
"win": 32,
"draw": 4,
"loss": 2,
"goals_for": 106,
"goals_against": 27,
"goal_diff": 79,
"points": 100
}]
}]
}]}
So I created a Response which is :
public class StandingsResponse {
#SerializedName("generated_at")
#Expose
private String mGeneratedAt;
#SerializedName("schema")
#Expose
private String mSchema;
#SerializedName("standings")
private List<Standings> mStandings;
public String getGeneratedAt() {
return mGeneratedAt;
}
public void setGeneratedAt(String generatedAt) {
mGeneratedAt = generatedAt;
}
public String getSchema() {
return mSchema;
}
public void setSchema(String schema) {
mSchema = schema;
}
public List<Standings> getStandings() {
return mStandings;
}
public void setStandings(List<Standings> standings) {
mStandings = standings;
}
The Response has a List of Standings, The standings POJO has a list of groups:
public class Standings {
#SerializedName("groups")
#Expose
private List<Group> mGroup;
public List<Group> getGroup() {
return mGroup;
}
public void setGroup(List<Group> group) {
mGroup = group;
}
The Groups POJO has a list of TeamStandings:
public class Group {
#SerializedName("team_standings")
#Expose
private List<TeamStandings> mTeamStandings;
public List<TeamStandings> getTeamStandings() {
return mTeamStandings;
}
public void setTeamStandings(List<TeamStandings> teamStandings) {
mTeamStandings = teamStandings;
}
And TeamStandings has all the data I want to display:
public class TeamStandings {
#SerializedName("team")
#Expose
private Team mTeam;
#SerializedName("rank")
#Expose
private Integer mRank;
#SerializedName("played")
#Expose
private Integer mPlayed;
#SerializedName("win")
#Expose
private Integer mWin;
#SerializedName("draw")
#Expose
private Integer mDraw;
#SerializedName("lose")
#Expose
private Integer mLose;
#SerializedName("goals_for")
#Expose
private Integer mGoalsFor;
#SerializedName("goals_against")
#Expose
private Integer mGoalsAgainst;
#SerializedName("goal_diff")
#Expose
private Integer mGoalsDiff;
#SerializedName("points")
#Expose
private Integer mPoints;
public Integer getGoalsFor() {
return mGoalsFor;
}
public void setGoalsFor(Integer goalsFor) {
mGoalsFor = goalsFor;
}
public Integer getGoalsAgainst() {
return mGoalsAgainst;
}
public void setGoalsAgainst(Integer goalsAgainst) {
mGoalsAgainst = goalsAgainst;
}
public Integer getGoalsDiff() {
return mGoalsDiff;
}
public void setGoalsDiff(Integer goalsDiff) {
mGoalsDiff = goalsDiff;
}
public Integer getRank() {
return mRank;
}
public void setRank(Integer rank) {
mRank = rank;
}
public Integer getPlayed() {
return mPlayed;
}
public void setPlayed(Integer played) {
mPlayed = played;
}
public Integer getWin() {
return mWin;
}
public void setWin(Integer win) {
mWin = win;
}
public Integer getDraw() {
return mDraw;
}
public void setDraw(Integer draw) {
mDraw = draw;
}
public Integer getLose() {
return mLose;
}
public void setLose(Integer lose) {
mLose = lose;
}
public Integer getPoints() {
return mPoints;
}
public void setPoints(Integer points) {
mPoints = points;
}
public Team getTeam() {
return mTeam;
}
public void setTeam(Team team) {
mTeam = team;
}
I am calling the response and correctly attaching the response body to the Adapter but for some reason the App crashes and I see this error in the Logcat:
android.content.res.Resources$NotFoundException: String resource ID #0x1
at android.content.res.Resources.getText(Resources.java:339)
at android.widget.TextView.setText(TextView.java:5496)
at com.mad.footstats.ui.adapters.StandingsAdapter.onBindViewHolder(StandingsAdapter.java:62)
Edit: this is my Adapter:
public class StandingsAdapter extends RecyclerView.Adapter<StandingsAdapter.StandingsViewHolder> {
private List<Standings> mStandings;
private int mRowLayout;
private Context mContext;
public class StandingsViewHolder extends RecyclerView.ViewHolder {
LinearLayout standingsLayout;
TextView teamRank, teamName, teamPlayed, teamWon, teamDraw,
teamLose, teamFor, teamAgainst, teamGd, teamPts;
public StandingsViewHolder(View itemView) {
super(itemView);
standingsLayout = itemView.findViewById(R.id.standings_layout);
teamRank = itemView.findViewById(R.id.standings_team_rank);
teamName = itemView.findViewById(R.id.standings_team_name);
teamPlayed = itemView.findViewById(R.id.standings_team_played);
teamWon = itemView.findViewById(R.id.standings_team_won);
teamDraw = itemView.findViewById(R.id.standings_team_draw);
teamLose = itemView.findViewById(R.id.standings_team_lost);
teamFor = itemView.findViewById(R.id.standings_team_for);
teamAgainst = itemView.findViewById(R.id.standings_team_against);
teamGd = itemView.findViewById(R.id.standings_team_gd);
teamPts = itemView.findViewById(R.id.standings_team_pts);
}
}
public StandingsAdapter (List<Standings> standings, int rowLayout,
Context context){
mStandings = standings;
mRowLayout = rowLayout;
mContext = context;
}
#Override
public StandingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(mRowLayout, parent, false);
StandingsViewHolder holder = new StandingsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(StandingsViewHolder holder, int position) {
holder.teamRank.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getRank());
holder.teamName.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getTeam().getName());
holder.teamPlayed.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getPlayed());
holder.teamWon.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getWin());
holder.teamDraw.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getDraw());
holder.teamLose.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getLose());
holder.teamFor.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getGoalsFor());
holder.teamAgainst.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getGoalsAgainst());
holder.teamGd.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getGoalsDiff());
holder.teamPts.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getPoints());
}
#Override
public int getItemCount() {
return mStandings.size();
}
This exception come because you set integer value in textview so you should be do type casting of String .
For Example
you doing
mTxtView.setText(mList.get(position).getMETHOD_WHICH_RETURN_INT())
you should be do
mTxtView.setText(""+mList.get(position).getMETHOD_WHICH_RETURN_INT())
You should be
holder.teamRank.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getRank());
holder.teamPlayed.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getPlayed());
holder.teamWon.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getWin());
holder.teamDraw.setText(mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getDraw());
holder.teamLose.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getLose());
holder.teamFor.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getGoalsFor());
holder.teamAgainst.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getGoalsAgainst());
holder.teamGd.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getGoalsDiff());
holder.teamPts.setText(""+mStandings.get(position).getGroup().get(position)
.getTeamStandings().get(position).getPoints());

How to populate recyclerview with compex json data using retrofit?

please advise. I have a complex json object which I get requesting to openweathermap API using Retrofit and GSONConverterFactory. I have a trouble requesting forecast for 5 days, I can't populate my Recyclerview with the data, something goes wrong. I can't get what should I write in the onResponse method of Retrofit callback.
Retrofit requests are all with code 200 and message OK. So trouble is not in this area.
Thank you in advance!
Here is structure of Json object
WeatherData is a root Object which I get parsing my Json, please find the code below. All the code for it (as well as for other POJO's is imported from jsonschema2pojo:
public class WeatherData {
#SerializedName("coord")
#Expose
private Coord coord;
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
#SerializedName("base")
#Expose
private String base;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("visibility")
#Expose
private Integer visibility;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("dt")
#Expose
private Long dt;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("cod")
#Expose
private Integer cod;
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Integer getVisibility() {
return visibility;
}
public void setVisibility(Integer visibility) {
this.visibility = visibility;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Long getDt() {
return dt;
}
public void setDt(Long dt) {
this.dt = dt;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCod() {
return cod;
}
public void setCod(Integer cod) {
this.cod = cod;
}
Here is my RecyclerView.Adapter
public class Forecast5DaysAdapter extends RecyclerView.Adapter<Forecast5DaysAdapter.ForecastHolder> {
List<WeatherData> mWeatherDataList;
public static class ForecastHolder extends RecyclerView.ViewHolder {
public TextView dateOnDate;
public ImageView weatherOnDate;
public TextView tempOnDate;
public TextView windSpeedOnDate;
public ForecastHolder(View view) {
super(view);
dateOnDate = (TextView) view.findViewById(R.id.dateOnDate);
windSpeedOnDate = (TextView) view.findViewById(R.id.windSpeedOnDate);
tempOnDate = (TextView) view.findViewById(R.id.tempOnDate);
weatherOnDate = (ImageView) view.findViewById(R.id.imageOnDate);
}
}
public Forecast5DaysAdapter(List<WeatherData> mWeatherDataList) {
this.mWeatherDataList = mWeatherDataList;
}
#Override
public ForecastHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.forecast_card, parent, false);
final ForecastHolder forecastHolder = new ForecastHolder(view);
return forecastHolder;
}
#Override
public void onBindViewHolder(ForecastHolder holder, int position) {
//FILLING THE CARDS IN RECYCLERVIEW WITH INFORMATION
holder.dateOnDate.setText(mWeatherDataList.get(position).getDt().toString());
holder.tempOnDate.setText(mWeatherDataList.get(position).getMain().getTemp().toString());
holder.windSpeedOnDate.setText(mWeatherDataList.get(position).getWind().getSpeed().toString());
Picasso.with(holder.weatherOnDate.getContext()).load("http://openweathermap.org/img/w/" + mWeatherDataList.get(position).getWeather().get(position).getIcon() + ".png").into(holder.weatherOnDate);
}
#Override
public int getItemCount() {
return 0;
}
Here is the class I want to display the Recyclerview
public class Forecast5Days extends AppCompatActivity {
private static final String API_KEY = "HERE IS THE KEY";
private RecyclerView forecastRecycler;
private ArrayList<WeatherData> mWeatherData;
private Forecast5DaysAdapter forecast5DaysAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forecast_5_days);
forecastRecycler = (RecyclerView) findViewById(R.id.forecast_5_daysRecycler);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
forecastRecycler.setLayoutManager(layoutManager);
final Forecast5DaysAdapter forecast5DaysAdapter = new Forecast5DaysAdapter(mWeatherData);
forecastRecycler.setAdapter(forecast5DaysAdapter);
Intent intent = getIntent();
final String cityName = intent.getStringExtra("cityName");
if (!cityName.isEmpty()) {
Call<WeatherData> call = RetrofitBuilderHelper.weatherAPI.getForecast5Days(cityName, "ru", "metric", API_KEY);
call.enqueue(new Callback<WeatherData>() {
#Override
public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
//????????????????
}
#Override
public void onFailure(Call<WeatherData> call, Throwable t) {
Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with request", Toast.LENGTH_LONG);
toast.show();
}
});
} else {
Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with intent", Toast.LENGTH_LONG);
toast.show();
}
}
Your onResponse should be like this
call.enqueue(new Callback<WeatherData>() {
#Override
public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
if(response.isSuccessful() && response.body != null) {
WeatherData data = response.body();
}
}
#Override
public void onFailure(Call<WeatherData> call, Throwable t) {
Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with request", Toast.LENGTH_LONG);
toast.show();
}
});
Also your Call is Call<WeatherData> which will give you a single object. If you want a list of objects your call should be Call<List<WeatherData>>
I think you are looking to pass Weatherinstead of WeatherData so your onResponse should look like
call.enqueue(new Callback<WeatherData>() {
#Override
public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
if(response.isSuccessful() && response.body != null) {
WeatherData data = response.body();
List<Weather> weatherList = data.getWeatherList();
//Pass this list to your adapter
}
}
#Override
public void onFailure(Call<WeatherData> call, Throwable t) {
Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with request", Toast.LENGTH_LONG);
toast.show();
}
});
Your JSON return is a List not only a Single WeatherData Object.
So all you should have to do is a cange of the Expected return value.
Try this:
Call<List<WeatherData>> call = RetrofitBuilderHelper.weatherAPI.getForecast5Days(cityName, "ru", "metric", API_KEY);
call.enqueue(new Callback<List<WeatherData>>() {
#Override
public void onResponse(Call<List<WeatherData>> call, Response<List<WeatherData>> response) {
forecastRecycler.weatherList = response.body();
forecastRecycler.notifyDatasetChanged();
}

Categories

Resources