I am using firebase recycler options to retrieve data needed from firebase database, which in this case 3 boolean value. In the adapter, i found out that all boolean value retrieved is false. However, when i start the activity and select the spinner, the spinner correctly set up the boolean value in firebase database. Moreover, the selection on the spinner not set correctly according to the data, as it retrieve all false in the database.
I attached my helper class, adapter onbindviewholder and onitemselected.
BookingModal.class
public class BookingModal {
private String DATE;
private String TIME;
private String UID;
private boolean approved;
private boolean pending;
private boolean rejected;
public BookingModal(String DATE, String TIME, String UID, boolean approved, boolean pending, boolean rejected) {
this.DATE = DATE;
this.TIME = TIME;
this.UID = UID;
this.approved = approved;
this.pending = pending;
this.rejected = rejected;
}
public BookingModal(){}
public String getDATE() {
return DATE;
}
public void setDATE(String DATE) {
this.DATE = DATE;
}
public String getTIME() {
return TIME;
}
public void setTIME(String TIME) {
this.TIME = TIME;
}
public String getUID() {
return UID;
}
public void setUID(String UID) {
this.UID = UID;
}
public boolean Approved() {
return approved;
}
public void setApproved(boolean approved) {
this.approved = approved;
}
public boolean Pending() {
return pending;
}
public void setPending(boolean pending) {
this.pending = pending;
}
public boolean Rejected() {
return rejected;
}
public void setRejected(boolean rejected) {
this.rejected = rejected;
}
}
Adapter onbindviewholder class.
#Override
protected void onBindViewHolder(#NonNull BookingVH holder, int position, #NonNull BookingModal model) {
holder.date.setText(model.getDATE());
UserModal userModalDetail = findbyProperty(userModalList, model.getUID());
if (userModalDetail != null) {
holder.name.setText(userModalDetail.getName());
holder.matric.setText(userModalDetail.getMatricnumber());
onStatusSelected.onSelected(holder.status, userModalDetail.getUID(), model);
}
Log.d("booleanvalue", model.Pending() + " - "+model.Approved()+" - "+model.Rejected());
}
onitemselected for spinner
#Override
public void onSelected(Spinner v, String uid, BookingModal modal) {
Log.d("modalboolean", String.valueOf(modal.Approved()));
v.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
checker.clear();
if (i == 0){
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isPending").setValue(true);
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isApproved").setValue(false);
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isRejected").setValue(false);
} else if (i == 1){
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isApproved").setValue(true);
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isPending").setValue(false);
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isRejected").setValue(false);
} else if (i == 2){
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isRejected").setValue(true);
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isApproved").setValue(false);
mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).child("isPending").setValue(false);
}
v.setSelection(i, true);
Log.d("CheckerMap", checker.toString());
// mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid).updateChildren(checker);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
Really appreciate for any help. Thank you in advance !
EDITED
Here is my json db structure
{
"Admin": {
"e7oK2kaWLDW5SdSnBS1KEKXazNH3": {
"admin": true,
"departmentnumber": "",
"email": "admin#mail.com",
"matricnumber": "",
"name": "admin1",
"password": "admin123",
"phonenumber": ""
}
},
"Bookings": {
"Kompleks Sukan A": {
"Pending": {
"AQ7W0xjc0kYZTg7mz5LH8m7wAXF3": {
"DATE": "19/01/2023",
"TIME": "1-2PM",
"UID": "AQ7W0xjc0kYZTg7mz5LH8m7wAXF3",
"isApproved": true,
"isPending": false,
"isRejected": false
},
"a59Pmpt9kvNTO6yFjXspGRqmlGh1": {
"date": "26/01/2023",
"isApproved": false,
"isPending": false,
"isRejected": true,
"time": "1-2PM",
"uid": "a59Pmpt9kvNTO6yFjXspGRqmlGh1"
}
}
}
},
"Kompleks Sukan A": {
"1-2PM": false,
"10-11AM": false,
"11-12PM": false,
"12-1PM": false,
"2-3PM": false,
"3-4PM": false,
"4-5PM": false,
"5-6PM": false,
"6-7PM": false,
"9-10AM": false
},
"Users": {
"AQ7W0xjc0kYZTg7mz5LH8m7wAXF3": {
"admin": false,
"departmentnumber": "",
"email": "user1#mail.com",
"matricnumber": "",
"name": "test",
"password": "user123",
"phonenumber": "",
"uid": "AQ7W0xjc0kYZTg7mz5LH8m7wAXF3"
},
"a59Pmpt9kvNTO6yFjXspGRqmlGh1": {
"admin": false,
"departmentnumber": "",
"email": "ceyn#mail.com",
"matricnumber": "53104119052",
"name": "ceyn",
"password": "ceyn123",
"phonenumber": "01112872692",
"uid": "a59Pmpt9kvNTO6yFjXspGRqmlGh1"
}
}
}
I ended up using a single string as status checking. Changing it easier to use with spinner.
In your POJO classes, you have declared
private boolean approved;
private boolean pending;
private boolean rejected;
while generating build, android change variable names of boolean types.
To prevent this changing, you can keep your model classes in Proguard Rules as follow:
-keep class com.example.myapplication.models.**
keep all of your classes under models package. Now it will not change the names of variables.
Related
Showing error on getValue(User.class) in explore_fragment.
My explore_fragment is:
public class exploreFragment extends Fragment {
FragmentExploreBinding binding;
ArrayList<User> list = new ArrayList<>();
FirebaseAuth auth;
FirebaseDatabase database;
public exploreFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
auth = FirebaseAuth.getInstance();
database= FirebaseDatabase.getInstance();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding= FragmentExploreBinding.inflate(inflater, container, false);
UserAdapter adapter = new UserAdapter(getContext(),list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
binding.usersRV.setLayoutManager(layoutManager);
binding.usersRV.setAdapter(adapter);
database.getReference().child("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
User user = dataSnapshot.getValue(User.class);
user.setUserID(dataSnapshot.getKey());
if(!dataSnapshot.getKey().equals(FirebaseAuth.getInstance().getUid())){
list.add(user);
}
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
return binding.getRoot();
}
}
User_model is:
public class User {
private String name, profession,email,password,cname;
private String profile;
private String userReff;
private int guidedCount;
private String userID;
private String coverPhoto;
public User() {
}
public int getGuidedCount() {
return guidedCount;
}
public void setGuidedCount(int guidedCount) {
this.guidedCount = guidedCount;
}
public String getCoverPhoto() {
return coverPhoto;
}
public void setCoverPhoto(String coverPhoto) {
this.coverPhoto = coverPhoto;
}
public User(String name, String profession, String email, String password, String cname) {
this.name = name;
this.profession = profession;
this.email = email;
this.password = password;
this.cname = cname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getUserReff() {
return userReff;
}
public void setUserReff(String userReff) {
this.userReff = userReff;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
}
User_adapter is:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.viewHolder>{
Context context;
ArrayList<User> list;
public UserAdapter(Context context, ArrayList<User> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.user_sample,parent,false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
User user = list.get(position);
Picasso.get().load(user.getProfile()).placeholder(R.drawable.placeholder).into(holder.binding.profileImage);
holder.binding.name.setText(user.getName());
holder.binding.profession.setText(user.getProfession());
holder.binding.viewprofilebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view){
String visiter = list.get(holder.getAdapterPosition()).getUserID();
Intent intent= new Intent(context, VActivity.class);
intent.putExtra("usersid",visiter).toString();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class viewHolder extends RecyclerView.ViewHolder{
UserSampleBinding binding;
public viewHolder(#NonNull View itemView) {
super(itemView);
binding = UserSampleBinding.bind(itemView);
}
}
}
Error i am getting is:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.guided_app, PID: 2744
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertInteger(CustomClassMapper.java:364)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToPrimitive(CustomClassMapper.java:290)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:215)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:179)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:48)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:593)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.example.guided_app.fragment.exploreFragment$1.onDataChange(exploreFragment.java:60)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
The firebase database is:
"Users": {
"59fLuGGNugPcgp6b725cFnKIzKC2": {
"cname": "LIT",
"email": "Stephen#gmail.com",
"guidedCount": 0,
"name": "Stephen Wade",
"password": "123456",
"profession": "Developer # Adobe"
},
"7kpNGqcHeBfNqf8GrVK2Hpew0L62": {
"cname": "BIT",
"email": "anshul#gmail.com",
"guided": {
"FOQEVbKRpNYjfzAJCp1XQtnvRlh2": {
"guidedAt": 1670152487063,
"guidedBy": "FOQEVbKRpNYjfzAJCp1XQtnvRlh2"
},
"y3pV1GhdLqOnteMO64U2F4o8mMu2": {
"guidedAt": 1670151228825,
"guidedBy": "y3pV1GhdLqOnteMO64U2F4o8mMu2"
}
},
"guidedCount": 2,
"name": "Anshul Lanjewar",
"password": "123456",
"profession": "SDE # Google"
},
"FOQEVbKRpNYjfzAJCp1XQtnvRlh2": {
"cname": "SIT",
"email": "Tanvi#gmail.com",
"guidedCount": 0,
"name": "Tanvi Colson",
"password": "123456",
"profession": "Analyst # Google"
},
"Jj2RH3iopgdLU6AC3VKeeaMKAXx1": {
"cname": "PIT",
"email": "Shana#gmail.com",
"guidedCount": 0,
"name": "Shana Sharma",
"password": "123456",
"profession": "FullStack # Netflix"
},
"gAzcrP1IYmQI0ht4qfH9WGt9U7F2": {
"cname": "MIT",
"email": "John#gmail.com",
"guided": {
"7kpNGqcHeBfNqf8GrVK2Hpew0L62": {
"guidedAt": 1670614050015,
"guidedBy": "7kpNGqcHeBfNqf8GrVK2Hpew0L62"
}
},
"guidedCount": "gAzcrP1IYmQI0ht4qfH9WGt9U7F2",
"name": "John Adams",
"password": "123456",
"profession": "Developer # Apple"
},
"y3pV1GhdLqOnteMO64U2F4o8mMu2": {
"cname": "BIT",
"email": "kumar#gmail.com",
"guided": {
"7kpNGqcHeBfNqf8GrVK2Hpew0L62": {
"guidedAt": 1670154254299,
"guidedBy": "7kpNGqcHeBfNqf8GrVK2Hpew0L62"
}
},
"guidedCount": 1,
"name": "Kumar Mishra",
"password": "123456",
"profession": "SDE # Microsoft"
}
}
I recently started with android development, so was just stucked.
I want to create an explore_fragment in which list of users is added in recyclerView and with view_profile button we can view user profile.
As expected, the following error:
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int
Arrives due to the fact that an int-type field holds a value of type String. So when deserializing, the guidedCount field is expected to hold a value of type int and not String, hence the error. The node that is responsible for the Exception is:
"guidedCount": "gAzcrP1IYmQI0ht4qfH9WGt9U7F2",
See, it holds a UID rather than a number. So to solve this, change that UID with a number.
I am trying to get data from json that work for first portion but not for nested json object.I want to get the province and city from json object.
I am trying to get data from json that work for first portion but not for nested json object.I want to get the province and city from json object.
In province object i want province string and in city i want city string
........................MY JSON.................
{
"ads": [
{
"id": 8,
"title": "Software Engineering",
"description": "A book for software engineers",
"price": 100,
"user_id": 1,
"province_id": 4,
"city_id": 5,
"subject_id": 1,
"level_id": 3,
"active": 1,
"created_at": "2019-04-20 04:35:00",
"updated_at": "2019-04-20 04:35:00",
"province": {
"id": 4,
"province": "Blochistan",
"created_at": null,
"updated_at": null
},
"city": {
"id": 5,
"city": "Quetta",
"province_id": 4,
"created_at": null,
"updated_at": null
}
}
]
}
public class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.CustomViewHolder> {
private List<Data> adsList;
private Context context;
public AdsAdapter(List<Data> dataList,Context context) {
this.adsList=dataList;
this.context=context;
}
#NonNull
#Override
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.ads_list, viewGroup, false);
return new CustomViewHolder(itemView,adsList,context);
}
#Override
public void onBindViewHolder(#NonNull CustomViewHolder customViewHolder, int i) {
Data data = adsList.get(i);
customViewHolder.ad_title.setText(data.getTitle());
customViewHolder.ad_price.setText(data.getPrice().toString());
// customViewHolder.ad_city.setText(();
}
#Override
public int getItemCount() {
return adsList.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView ad_title,ad_price,ad_province,ad_city;
private List<Data> adsList;
private Context context;
public CustomViewHolder(#NonNull View itemView,List<Data> adsList,Context context) {
super(itemView);
this.adsList=adsList;
this.context=context;
itemView.setOnClickListener(this);
ad_title = (TextView)itemView.findViewById(R.id.current_page);
ad_price = itemView.findViewById(R.id.ad_price);
ad_province = itemView.findViewById(R.id.province);
ad_city = itemView.findViewById(R.id.city);
}
#Override
public void onClick(View v) {
int position=getAdapterPosition();
Data data = this.adsList.get(position);
Intent intent = new Intent(this.context,AdDetail.class);
intent.putExtra("title",data.getTitle());
intent.putExtra("discrip",data.getDescription());
intent.putExtra("price",data.getPrice().toString());
intent.putExtra("create",data.getCreatedAt().toString());
this.context.startActivity(intent);
}
}
}
my application terminated when i access province string.
Model Class
public class Province {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("province")
#Expose
private String province;
#SerializedName("created_at")
#Expose
private Object createdAt;
#SerializedName("updated_at")
#Expose
private Object updatedAt;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public Object getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Object createdAt) {
this.createdAt = createdAt;
}
public Object getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Object updatedAt) {
this.updatedAt = updatedAt;
}
}
Call call = api.getAds(parse_subject_id,parse_level_id);
/**
* Enqueue Callback will be call when get response...
*/
call.enqueue(new Callback<SubjectList>() {
#Override
public void onResponse(Call<SubjectList> call, Response<SubjectList> response) {
pDialog.dismiss();
if (response.isSuccessful()) {
/**
* Got Successfully
*/
adsList = response.body().getAds();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view_Ads);
adsAdapter = new AdsAdapter(adsList,getApplicationContext());
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adsAdapter);
/////////////////////////////////////
}
}
#Override
public void onFailure(Call<SubjectList> call, Throwable t) {
pDialog.dismiss();
}
});
hare i am calling the adapter and pass parameters
From city object you can directly get province_id
I'm a newbie in the Android development an am trying to parse complex JSON structure with the help of rertofit library from the http://api.tvmaze.com/search/shows?q=girls. But my project fails in loading data. I suppose that the problem is in the GSON model, but I'm in complete bewilderment what's exactly wrong.
I need to fetch only image and title
I have already included the internet permission in the manifest
response looks like that:
[
{
"score": 17.314238,
"show": {
"id": 139,
"url": "http://www.tvmaze.com/shows/139/girls",
"name": "Girls",
"type": "Scripted",
"language": "English",
"genres": [
"Drama",
"Romance"
],
"status": "Ended",
"runtime": 30,
"premiered": "2012-04-15",
"officialSite": "http://www.hbo.com/girls",
"schedule": {
"time": "22:00",
"days": [
"Sunday"
]
},
"rating": {
"average": 6.7
},
"weight": 94,
"network": {
"id": 8,
"name": "HBO",
"country": {
"name": "United States",
"code": "US",
"timezone": "America/New_York"
}
},
"webChannel": null,
"externals": {
"tvrage": 30124,
"thetvdb": 220411,
"imdb": "tt1723816"
},
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/31/78286.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/31/78286.jpg"
},
"summary": "<p>This Emmy winning series is a comic look at the assorted humiliations and rare triumphs of a group of girls in their 20s.</p>",
"updated": 1538265422,
"_links": {
"self": {
"href": "http://api.tvmaze.com/shows/139"
},
"previousepisode": {
"href": "http://api.tvmaze.com/episodes/1079686"
}
}
}
},
{
"score": 13.229476,
"show": {
"id": 23542,
"url": "http://www.tvmaze.com/shows/23542/good-girls",
"name": "Good Girls",
"type": "Scripted",
"language": "English",
"genres": [
"Drama",
"Comedy",
"Crime"
],
"status": "Running",
"runtime": 60,
"premiered": "2018-02-26",
"officialSite": "https://www.nbc.com/good-girls?nbc=1",
"schedule": {
"time": "22:00",
"days": [
"Monday"
]
},
"rating": {
"average": 7
},
"weight": 92,
"network": {
"id": 1,
"name": "NBC",
"country": {
"name": "United States",
"code": "US",
"timezone": "America/New_York"
}
},
"webChannel": null,
"externals": {
"tvrage": null,
"thetvdb": 328577,
"imdb": "tt6474378"
},
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/141/354343.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/141/354343.jpg"
},
"summary": "<p><b>Good Girls</b> follows three \"good girl\" suburban wives and mothers who suddenly find themselves in desperate circumstances and decide to stop playing it safe, and risk everything to take their power back.</p>",
"updated": 1532345475,
"_links": {
"self": {
"href": "http://api.tvmaze.com/shows/23542"
},
"previousepisode": {
"href": "http://api.tvmaze.com/episodes/1425058"
}
}
}
},
......
]
I build my model class for fetching image and title, because i need only htese two items:
public class Image:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Image {
#SerializedName("medium")
#Expose
private String medium;
#SerializedName("original")
#Expose
private String original;
public String getMedium() {
return medium;
}
public void setMedium(String medium) {
this.medium = medium;
}
public String getOriginal() {
return original;
}
public void setOriginal(String original) {
this.original = original;
}
}
public class Movie:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Movie {
#SerializedName("name")
#Expose
private String name;
#SerializedName("image")
#Expose
private Image image;
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public Image getImageUrl() {
return image;
}
public void setImageUrl(Image image) {
this.image = image;
}
}
A recyclerview adapter for those items:
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MyViewHolder> implements Filterable {
private List<Movie> movieList;
private List<Movie> movieListFiltered;
private Context context;
public void setMovieList(Context context,final List<Movie> movieList){
this.context = context;
this.movieList = movieList;
this.movieListFiltered = movieList;
}
#Override
public MovieAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MovieAdapter.MyViewHolder holder, int position) {
holder.title.setText(movieListFiltered.get(position).getTitle());
GlideApp.with(context).load(movieList.get(position).getImageUrl()).listener(new RequestListener() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
// Log the GlideException here (locally or with a remote logging framework):
Log.e(TAG, "Load failed", e);
// You can also log the individual causes:
for (Throwable t : e.getRootCauses()) {
Log.e(TAG, "Caused by", t);
}
// Or, to log all root causes locally, you can use the built in helper method:
e.logRootCauses(TAG);
return false; // Allow calling onLoadFailed on the Target.
}
#Override
public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
// Log successes here or use DataSource to keep track of cache hits and misses.
return false; // Allow calling onResourceReady on the Target.
}
}).into(holder.image);
}
#Override
public int getItemCount() {
if(movieList != null&& movieListFiltered!=null){
return movieListFiltered.size();
} else {
return 0;
}
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
movieListFiltered = movieList;
} else {
List<Movie> filteredList = new ArrayList<>();
for (Movie movie : movieList) {
if (movie.getTitle().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(movie);
}
}
movieListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = movieListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
movieListFiltered = (ArrayList<Movie>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
ImageView image;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
image = (ImageView)view.findViewById(R.id.image);
}
}
}
My MainActivity:
public class MainActivity extends AppCompatActivity {
private SearchView searchView;
private RecyclerView recyclerView;
private MovieAdapter movieAdapter;
private List<Movie> movieList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
movieList = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
movieAdapter = new MovieAdapter();
recyclerView.setAdapter(movieAdapter);
ApiInterface apiService = TvMazeApiClient.getClient().create(ApiInterface.class);
Call<List<Movie>> call = apiService.getMovies();
call.enqueue(new Callback<List<Movie>>() {
#Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
if(movieList != null) {
movieList = response.body();
Log.d("TAG", "Response = " + movieList);
movieAdapter.setMovieList(getApplicationContext(), movieList);
}
else{
Toast.makeText(MainActivity.this,"error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<List<Movie>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
Toast.makeText(MainActivity.this,t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
movieAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
movieAdapter.getFilter().filter(query);
return false;
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_search) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
return;
}
super.onBackPressed();
}}
my xml file for item:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="160dp"
android:orientation="horizontal"
android:padding="8dp">
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="16sp"
android:textStyle="bold"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Interface:
public interface ApiInterface {
#GET("search/shows?q=girls")
Call <List<Movie>> getMovies();
}
Client:
public class TvMazeApiClient {
public static String BASE_URL ="http://api.tvmaze.com/";
private static Retrofit retrofit;
public static Retrofit getClient(){
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Thanks in advance for any help
The fields "name" and "image" that you are trying to parse are nested in a JSON object "show". You need to parse this field as well.
public interface ApiInterface {
#GET("search/shows?q=girls")
Call <List<MovieResponse>> getMovies();
}
Create a new Java object
public class MovieResponse {
#SerializedName("show")
#Expose
private Movie show;
public Movie getShow() {
return show;
}
}
I've gone through a few questions on here and I'm absolutely stuck as to how to proceed. I am parsing data using GSON and I have added the results to my recyclerview in addition to adding the notifydatachange to the adapter and yet my recycler view is still empty. My logcat shows nothing wrong and is receiving information from the server. Can someone let me know what I have done incorrectly? My RecyclerView adapter seems ok and I think I added the necessary codes to my fragment.
Fragment Activity:
public class WeatherAppFragment extends Fragment implements Listener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private SearchView searchView = null;
private SearchView.OnQueryTextListener queryTextListener;
RecyclerView mRecyclerView;
String mStatusView;
List<ForecastWeatherList> items = new ArrayList<>();
RecyclerViewAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_weather_app, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.addItemDecoration(new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL));
Log.d("debugMode", "I'm in onCreateView");
adapter = new RecyclerViewAdapter(items, mRecyclerView.getContext());
mRecyclerView.setAdapter(adapter);
new GetWeatherAync(this, mStatusView, api_key).execute();
return view;
}
private class GetWeatherAync extends AsyncTask<Context, Void, List<ForecastWeatherList>> {
private String TAG = GetWeatherAync.class.getSimpleName();
private final String serviceUrl;
private Context mContext;
private Listener listener;
HttpURLConnection urlConnection = null;
public GetWeatherAync(Listener listener, Object mStatusView, Object api_key) {
this.listener = listener;
this.serviceUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + "Miami" +"&APPID="+ " ";
}
#Override
protected List<ForecastWeatherList> doInBackground(Context...params) {
try {
Log.d("debugMode", "The application is in doInBackground");
URL url = new URL(serviceUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
Log.e(TAG, "Response code:" + urlConnection.getResponseCode());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
Log.e("response",bufferedReader.toString());
Gson gson = new Gson();
if (!bufferedReader.equals("")) {
ForecastWeatherListWrapper weatherWrapper = gson.fromJson(bufferedReader, ForecastWeatherListWrapper.class);
Log.e("something", weatherWrapper.getforecastWeatherLists().size() + "");
List<ForecastWeatherList> forecastWeatherLists = weatherWrapper.getforecastWeatherLists();
return forecastWeatherLists;
} else {
Log.e(TAG, "Error response code: " + urlConnection.getResponseCode());
}
}
} catch (Exception e) {
Log.e("catch","error");
System.out.println(e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(List<ForecastWeatherList> result) {
super.onPostExecute(result);
if (result != null) {
Log.e(TAG, "populate UI recycler view with gson converted data");
listener.afterSearch(result);
items.clear();
items.addAll(result);
adapter.notifyDataSetChanged();
} else{
Log.e(TAG, "Result is null");
// check if this Log shows up?
}
}
}
RecyclerViewAdapter:
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.ForecastRecycler> {
private List<ForecastWeatherList> mForecastWeatherDataList;
Context mContext;
public static class ForecastRecycler extends RecyclerView.ViewHolder{
public TextView currentTemp;
public TextView currentHumidity;
public TextView currentDescription;
public ImageView currentIcon;
public ForecastRecycler (View view) {
super (view);
currentTemp = (TextView) view.findViewById(R.id.current_temperature);
currentHumidity = (TextView) view.findViewById(R.id.current_humidity);
currentDescription = (TextView) view.findViewById(R.id.current_weather_description);
currentIcon = (ImageView) view.findViewById(R.id.current_weather_icon);
}
}
public RecyclerViewAdapter(List<ForecastWeatherList> mForecastWeatherDataList,Context mContext) {
this.mForecastWeatherDataList = mForecastWeatherDataList;
this.mContext = mContext;
}
#Override
public ForecastRecycler onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
return new ForecastRecycler(view);
}
#Override
public void onBindViewHolder( ForecastRecycler holder, int position) {
final ForecastWeatherList currentRecycler = mForecastWeatherDataList.get(position);
Log.d("weather", currentRecycler.getWeather().getDescription());
holder.currentTemp.setText((Double.toString(currentRecycler.getMain().getTemp())));
holder.currentHumidity.setText(currentRecycler.getMain().getHumidity());
holder.currentDescription.setText(currentRecycler.getWeather().getDescription());
Picasso.with(holder.currentIcon.getContext()).load(currentRecycler.getWeather().getIcon());
}
#Override
public int getItemCount() {
return mForecastWeatherDataList.size();
}
}
FragmentWeatherApp:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WeatherAppFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
Recycler Item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/current_city_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="#+id/current_weather_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/current_temperature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/current_humidity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/current_weather_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Here is my forecastweatherlistwrapper:
public class ForecastWeatherListWrapper {
#SerializedName("list")
#Expose
private List<ForecastWeatherList> forecastWeatherLists;
public List<ForecastWeatherList> getforecastWeatherLists() {
return forecastWeatherLists;
}
public void setforecastWeatherLists(List<ForecastWeatherList>
forecastWeatherItems){
this.forecastWeatherLists = forecastWeatherItems;
}
}
Here is my ForecastWeatherList:
public class ForecastWeatherList {
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("weather")
#Expose
private Weather weather = null;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("rain")
#Expose
private Rain rain;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("dt_txt")
#Expose
private String dtTxt;
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Weather getWeather() {
return (Weather) weather;
}
public void setWeather(Weather weather) {
this.weather = weather;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Rain getRain() {
return rain;
}
public void setRain(Rain rain) {
this.rain = rain;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public String getDtTxt() {
return dtTxt;
}
public void setDtTxt(String dtTxt) {
this.dtTxt = dtTxt;
}
}
Here are my some of GSON classes to parse JSON data. Some classes are Main, Clouds, etc
Here is my main class:
public class Main {
#SerializedName("temp")
#Expose
private Double temp;
#SerializedName("temp_min")
#Expose
private Double tempMin;
#SerializedName("temp_max")
#Expose
private Double tempMax;
#SerializedName("pressure")
#Expose
private Double pressure;
#SerializedName("sea_level")
#Expose
private Double seaLevel;
#SerializedName("grnd_level")
#Expose
private Double grndLevel;
#SerializedName("humidity")
#Expose
private Integer humidity;
#SerializedName("temp_kf")
#Expose
private Integer tempKf;
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Double getTempMin() {
return tempMin;
}
public void setTempMin(Double tempMin) {
this.tempMin = tempMin;
}
public Double getTempMax() {
return tempMax;
}
public void setTempMax(Double tempMax) {
this.tempMax = tempMax;
}
public Double getPressure() {
return pressure;
}
public void setPressure(Double pressure) {
this.pressure = pressure;
}
public Double getSeaLevel() {
return seaLevel;
}
public void setSeaLevel(Double seaLevel) {
this.seaLevel = seaLevel;
}
public Double getGrndLevel() {
return grndLevel;
}
public void setGrndLevel(Double grndLevel) {
this.grndLevel = grndLevel;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public Integer getTempKf() {
return tempKf;
}
public void setTempKf(Integer tempKf) {
this.tempKf = tempKf;
}
}
Here is my weather class:
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
Here is my raw string data (I think).
"cod":"200",
"message":0.0074,
"cnt":39,
"list":[
{
"dt":1534215600,
"main":{
"temp":293.24,
"temp_min":292.346,
"temp_max":293.24,
"pressure":1021.77,
"sea_level":1028.21,
"grnd_level":1021.77,
"humidity":100,
"temp_kf":0.89
},
"weather":[
{
"id":500,
"main":"Rain",
"description":"light rain",
"icon":"10n"
}
],
"clouds":{
"all":20
},
"wind":{
"speed":2.51,
"deg":275.001
},
"rain":{
"3h":0.0050000000000008
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-14 03:00:00"
},
{
"dt":1534226400,
"main":{
"temp":292.3,
"temp_min":291.706,
"temp_max":292.3,
"pressure":1020.99,
"sea_level":1027.42,
"grnd_level":1020.99,
"humidity":100,
"temp_kf":0.6
},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01n"
}
],
"clouds":{
"all":0
},
"wind":{
"speed":2.52,
"deg":294.505
},
"rain":{
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-14 06:00:00"
},
{
"dt":1534237200,
"main":{
"temp":291.07,
"temp_min":290.77,
"temp_max":291.07,
"pressure":1020.65,
"sea_level":1027.03,
"grnd_level":1020.65,
"humidity":100,
"temp_kf":0.3
},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01n"
}
],
"clouds":{
"all":0
},
"wind":{
"speed":1.31,
"deg":225.5
},
"rain":{
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-14 09:00:00"
},
{
"dt":1534248000,
"main":{
"temp":293.286,
"temp_min":293.286,
"temp_max":293.286,
"pressure":1020.78,
"sea_level":1027.17,
"grnd_level":1020.78,
"humidity":100,
"temp_kf":0
},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"02d"
}
],
"clouds":{
"all":8
},
"wind":{
"speed":2.83,
"deg":234.501
},
"rain":{
},
"sys":{
"pod":"d"
},
"dt_txt":"2018-08-14 12:00:00"
},
{
"dt":1534258800,
"main":{
"temp":298.671,
"temp_min":298.671,
"temp_max":298.671,
"pressure":1020.76,
"sea_level":1027.15,
"grnd_level":1020.76,
"humidity":92,
"temp_kf":0
},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01d"
}
],
"clouds":{
"all":0
},
"wind":{
"speed":2.71,
"deg":259.5
},
"rain":{
},
"sys":{
"pod":"d"
},
"dt_txt":"2018-08-14 15:00:00"
},
{
"dt":1534269600,
"main":{
"temp":300.7,
"temp_min":300.7,
"temp_max":300.7,
"pressure":1019.76,
"sea_level":1026.18,
"grnd_level":1019.76,
"humidity":83,
"temp_kf":0
},
"weather":[
{
"id":500,
"main":"Rain",
"description":"light rain",
"icon":"10d"
}
],
"clouds":{
"all":24
},
"wind":{
"speed":3.66,
"deg":285.503
},
"rain":{
"3h":1.11
},
"sys":{
"pod":"d"
},
"dt_txt":"2018-08-14 18:00:00"
},
{
"dt":1534280400,
"main":{
"temp":298.464,
"temp_min":298.464,
"temp_max":298.464,
"pressure":1019.68,
"sea_level":1025.97,
"grnd_level":1019.68,
"humidity":83,
"temp_kf":0
},
"weather":[
{
"id":500,
"main":"Rain",
"description":"light rain",
"icon":"10d"
}
],
"clouds":{
"all":48
},
"wind":{
"speed":3.27,
"deg":289.504
},
"rain":{
"3h":1.61
},
"sys":{
"pod":"d"
},
"dt_txt":"2018-08-14 21:00:00"
},
{
"dt":1534291200,
"main":{
"temp":297.882,
"temp_min":297.882,
"temp_max":297.882,
"pressure":1020,
"sea_level":1026.37,
"grnd_level":1020,
"humidity":82,
"temp_kf":0
},
"weather":[
{
"id":500,
"main":"Rain",
"description":"light rain",
"icon":"10n"
}
],
"clouds":{
"all":36
},
"wind":{
"speed":2.37,
"deg":275.004
},
"rain":{
"3h":0.13
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-15 00:00:00"
},
{
"dt":1534302000,
"main":{
"temp":295.242,
"temp_min":295.242,
"temp_max":295.242,
"pressure":1021.11,
"sea_level":1027.53,
"grnd_level":1021.11,
"humidity":94,
"temp_kf":0
},
"weather":[
{
"id":802,
"main":"Clouds",
"description":"scattered clouds",
"icon":"03n"
}
],
"clouds":{
"all":32
},
"wind":{
"speed":1.26,
"deg":313.002
},
"rain":{
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-15 03:00:00"
},
{
"dt":1534312800,
"main":{
"temp":294.05,
"temp_min":294.05,
"temp_max":294.05,
"pressure":1021.27,
"sea_level":1027.77,
"grnd_level":1021.27,
"humidity":100,
"temp_kf":0
},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01n"
}
],
"clouds":{
"all":0
},
"wind":{
"speed":2.46,
"deg":274.504
},
"rain":{
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-15 06:00:00"
},
{
"dt":1534323600,
"main":{
"temp":293.495,
"temp_min":293.495,
"temp_max":293.495,
"pressure":1021.36,
"sea_level":1027.7,
"grnd_level":1021.36,
"humidity":100,
"temp_kf":0
},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01n"
}
],
"clouds":{
"all":0
},
"wind":{
"speed":3.01,
"deg":277.505
},
"rain":{
},
"sys":{
"pod":"n"
},
"dt_txt":"2018-08-15 09:00:00"
],
"city":{
"id":4347778,
"name":"Baltimore",
"coord":{
"lat":39.2909,
"lon":-76.6108
},
"country":"US",
"population":620961
}
}
and here is my LogCat:
ksburneytwo.weathertest E/GetWeatherAync: Response code:200
ksburneytwo.weathertest E/response: java.io.BufferedReader#3d54b14
ksburneytwo.weathertest E/something: 40
ksburneytwo.weathertest E/GetWeatherAync: populate UI recycler view with gson converted data
I figured out what was happening. The postexecute was sending it to the listener.aftersearch. It was there that the results needed to be sent to the recyclerview in the form of items.addAll(results). The recyclerview now loads.
I have two tabs according to the number of category items (Mutton, Sea food) created dynamically.
In MenumainActivity I'm able to store Mutton items in ArrayList named listitemsAll and Sea food items in ArrayList named listitemsAll1 by doing this if (cat == 1)....
MenumainActivity:
public void onSuccess(String response) {
JSONObject obj = new JSONObject(response);
if (obj.getBoolean("status")) { 9
JSONObject hotels = obj.getJSONObject("Menu");
JSONArray items = hotels.getJSONArray("Items");
for (int j = 0; j < items.length(); j++) {
JSONObject hotel = items.getJSONObject(j);
categoryname = hotel.getString("name");
categoryid = hotel.getString("id");
hotelmenu = hotel.getJSONArray(categoryname);
listitems = new ArrayList<Menuclass>();
listitems1 = new ArrayList<Menuclass>();
for (int i = 0; i < hotelmenu.length(); i++) {
JSONObject menuitems = hotelmenu.getJSONObject(i);
itemname = menuitems.getString("name");
itemsprice = menuitems.getString("price");
itemtype = menuitems.getString("veg");
final int itemtypeint = Integer.parseInt(itemtype);
cat = Integer.parseInt(categoryid);
if (cat == 1) {
if (itemtypeint == 0) {
listitems.add(new Menuclass(itemname, itemsprice, R.drawable.nonveg));
}
else {
listitems.add(new Menuclass(itemname, itemsprice, R.drawable.vegicon));
}
else if (cat == 2) {
if (itemtypeint == 0) {
listitems1.add(new Menuclass(itemname, itemsprice, R.drawable.nonveg));
}
else {
listitems1.add(new Menuclass(itemname, itemsprice, R.drawable.vegicon));
}
}
}
listitemsAll.addAll(listitems);
listitemsAll.addAll(listitems1);
tabLayout.addTab(tabLayout.newTab().setText((categoryname)));
ViewPagerAdapter1 adapter = new ViewPagerAdapter1(getSupportFragmentManager(),items);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new
Once you have changed the JSON to
{
"Menu": {
"Items": [
{
"id": 1,
"code": "kd_sub1_mnu",
"name": "Mutton",
"status": "1",
"dishes": [
{
"id": 1,
"code": "hot1_sub1_mut",
"name": "Mutton Peper Fry",
"price": "100",
"veg": "0"
},
{
"id": 2,
"code": "hot1_sub2_mut",
"name": "Mutton Curry",
"price": "100",
"veg": "0"
},
{
"id": 3,
"code": "hot1_sub3_mut",
"name": "Mutton Rogan Josh",
"price": "100",
"veg": "0"
},
{
"id": 4,
"code": "hot1_sub4_mut",
"name": "Mutton Mohalai",
"price": "100",
"veg": "0"
}
]
},
{
"id": 2,
"code": "kd_sub2_mnu",
"name": "Sea Food",
"status": "1",
"dishes": [
{
"id": 1,
"code": "hot1_sub1_sf",
"name": "Fish Fry",
"price": "150",
"veg": "0"
},
{
"id": 2,
"code": "hot1_sub2_sf",
"name": "Chilly Fish",
"price": "250",
"veg": "0"
},
{
"id": 3,
"code": "hot1_sub3_sf",
"name": "Finger Fish",
"price": "350",
"veg": "0"
}
]
},
{
"id": 3,
"code": "kd_sub3_mnu",
"name": "Noodels",
"status": "1",
"dishes": [
{
"id": 1,
"code": "hot1_sub1_nd",
"name": "Chicken Noodels",
"price": "70",
"veg": "0"
},
{
"id": 3,
"code": "hot1_sub3_nd",
"name": "Veg Noodles",
"price": "55",
"veg": "1"
}
]
},
{
"id": 4,
"code": "kd_sub4_mnu",
"name": "Egg",
"status": "1",
"dishes": [
{
"id": 1,
"code": "hot1_sub1_egg",
"name": "Scrambled Egg",
"price": "20",
"veg": "0"
}
]
},
{
"id": 5,
"code": "kd_sub5_mnu",
"name": "Vegetarian Dishes",
"status": "1",
"dishes": [
{
"id": 1,
"code": "hot1_sub1_veg",
"name": "Veg./ Gobi Man.Dry",
"price": "60",
"veg": "1"
},
{
"id": 2,
"code": "hot1_sub2_veg",
"name": "Panner Manchoorian Dry",
"price": "60",
"veg": "1"
}
]
},
{
"id": 6,
"code": "kd_sub6_mnu",
"name": "Tandoor",
"status": "1",
"dishes": [
{
"id": 1,
"code": "hot1_sub1_ta",
"name": "Naan",
"price": "15",
"veg": "0"
},
{
"id": 2,
"code": "hot1_sub2_ta",
"name": "Butter naan",
"price": "20",
"veg": "0"
},
{
"id": 3,
"code": "hot1_sub3_ta",
"name": "Kulcha",
"price": "15",
"veg": "0"
}
]
}
]
},
"status": "true"
}
You can use http://www.jsonschema2pojo.org/ and paste your JSON object to create 4 Java classes as
public class Menuclass {
#SerializedName("Menu")
#Expose
private Menu menu;
#SerializedName("status")
#Expose
private String status;
public Menu getMenu() {
return menu;
}
public void setMenu(Menu menu) {
this.menu = menu;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
public class Dish {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("code")
#Expose
private String code;
#SerializedName("name")
#Expose
private String name;
#SerializedName("price")
#Expose
private String price;
#SerializedName("veg")
#Expose
private String veg;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getVeg() {
return veg;
}
public void setVeg(String veg) {
this.veg = veg;
}
}
public class Item {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("code")
#Expose
private String code;
#SerializedName("name")
#Expose
private String name;
#SerializedName("status")
#Expose
private String status;
#SerializedName("dishes")
#Expose
private List<Dish> dishes = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<Dish> getDishes() {
return dishes;
}
public void setDishes(List<Dish> dishes) {
this.dishes = dishes;
}
}
public class Menu {
#SerializedName("Items")
#Expose
private List<Item> items = null;
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
You may change the name of the classes if you want.
Now just change your onSuccess() method as follows:
Menuclass menuClassObject;
public void onSuccess(String response) {
menuClassObject = (new Gson()).fromJson(response,Menuclass.class);
}
Now the menuClassObject contains the response JSON converted to the class object.
MenuFragment's OnCreateView :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_tab1, container, false);
ListView listview = (ListView) view.findViewById(R.id.Listview1);
position = getArguments().getInt("position", 0);
MenuViewAdapter listViewAdapter = new MenuViewAdapter(getActivity(), menuClassObject,position);
listview.setAdapter(listViewAdapter);
return view;
}
}
Change your MenuViewAdapter :
public class MenuViewAdapter extends BaseAdapter {
private LayoutInflater layoutinflater;
private Menuclass menuClass;
private ArrayList<Dish> listStorage;
private Context context;
private int pagerPosition;
public MenuViewAdapter(Context context, Menuclass customMenuClass,int position) {
this.context = context;
layoutinflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
menuClass = customMenuClass;
pagerPosition = position;
listStorage = new ArrayList<>();
listStorage = menuClass.getMenu().getItems().get(position).getDishes();
}
#Override
public int getCount() {
return listStorage.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Dish dish = listStorage.get(position);
//Now Dish class has methods you need. Customize your view here based on the Dish.
}