How to handle two recyclerviews of the same layout in one activity? - java

I am using an MVVM structure in my project. In one activity I have two recyclerviews and one adapter. They are both using the same tasks_layout. I set the data this way:
final UnsortedAdapter adapter = new UnsortedAdapter();
eatFrog.setHasFixedSize(true);
eatFrog.setLayoutManager(new LinearLayoutManager(this));
eatFrog.setAdapter(adapter);
biologicalRhythms.setAdapter(adapter);
biologicalRhythms.setLayoutManager(new LinearLayoutManager(this));
biologicalRhythms.setHasFixedSize(true);
viewModel.getUnsortedWhereDateIs(currentDate).observe(this, new Observer<List<Unsorted>>() {
#Override
public void onChanged(List<Unsorted> unsorted) {
adapter.setData(EatAFrog(unsorted));
eatAFrogList = EatAFrog(unsorted);
adapter.setData(BiologicalRhythms(unsorted));
biologicalList = BiologicalRhythms(unsorted);
}
});
The point is that each recyclerview gets data of the same class "Unsorted", but data went through two different algorithms. If I do it this way, then two recyclerviews will have the same data, that went through second algorithm.
I tried to do different things. Firstly, I tried to use another instance of my adapter to the second recyclerview, but in that case there was no data displayed in the first recyclerview:
final UnsortedAdapter adapter = new UnsortedAdapter();
eatFrog.setHasFixedSize(true);
eatFrog.setLayoutManager(new LinearLayoutManager(this));
eatFrog.setAdapter(adapter);
final UnsortedAdapter adapter2 = new UnsortedAdapter();
biologicalRhythms.setAdapter(adapter2);
biologicalRhythms.setLayoutManager(new LinearLayoutManager(this));
biologicalRhythms.setHasFixedSize(true);
Seconly, I tried to create another adapter class, the same as third. I also created another layout - tasks2_layout, where I only changed the ids of the elements. Then in second new adapter I also changed them in a viewholder class.
My very first adapter looks like:
List<Unsorted> list = new ArrayList<>();
#NonNull
#Override
public UnsortedViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tasks_layout , parent, false);
return new UnsortedAdapter.UnsortedViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull UnsortedViewHolder holder, int position) {
Unsorted data = list.get(position);
holder.title.setText(data.getName());
holder.date.setText(data.getDate());
holder.category.setText(String.valueOf(data.getCategory()));
holder.attach.setText(String.valueOf(data.isAttach()));
holder.to.setText(String.valueOf(toTime(data.getDuration() + data.getTimeBegin())));
holder.from.setText(String.valueOf(toTime(data.getTimeBegin())));
}
public void setData(List<Unsorted> unsortedList){
this.list = unsortedList;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return list.size();
}
class UnsortedViewHolder extends RecyclerView.ViewHolder{
private TextView title;
private TextView date;
private TextView from;
private TextView to;
private TextView category;
private TextView attach;
public UnsortedViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.tv_title);
date = itemView.findViewById(R.id.tv_date);
from = itemView.findViewById(R.id.tv_from2);
to = itemView.findViewById(R.id.tv_to2);
category = itemView.findViewById(R.id.tv_category);
attach = itemView.findViewById(R.id.tv_attach);
}
}
And the second, new one:
List<Unsorted> list = new ArrayList<>();
#NonNull
#Override
public UnsortedViewHolder2 onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tasks2_layout , parent, false);
return new UnsortedAdapter2.UnsortedViewHolder2(itemView);
}
#Override
public void onBindViewHolder(#NonNull UnsortedViewHolder2 holder, int position) {
Unsorted data = list.get(position);
holder.title.setText(data.getName());
holder.date.setText(data.getDate());
holder.category.setText(String.valueOf(data.getCategory()));
holder.attach.setText(String.valueOf(data.isAttach()));
holder.to.setText(String.valueOf(toTime(data.getDuration() + data.getTimeBegin())));
holder.from.setText(String.valueOf(toTime(data.getTimeBegin())));
}
public void setData1(List<Unsorted> unsortedList){
this.list = unsortedList;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return list.size();
}
class UnsortedViewHolder2 extends RecyclerView.ViewHolder{
private TextView title;
private TextView date;
private TextView from;
private TextView to;
private TextView category;
private TextView attach;
public UnsortedViewHolder2(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.tv_title1);
date = itemView.findViewById(R.id.tv_date1);
from = itemView.findViewById(R.id.tv_from3);
to = itemView.findViewById(R.id.tv_to3);
category = itemView.findViewById(R.id.tv_category1);
attach = itemView.findViewById(R.id.tv_attach1);
}
}
When I have set a different adapter to each of the recyclerview, nothing changed. As in previous case, only second recyclerview was showing some data.
final UnsortedAdapter adapter = new UnsortedAdapter();
eatFrog.setHasFixedSize(true);
eatFrog.setLayoutManager(new LinearLayoutManager(this));
eatFrog.setAdapter(adapter);
final UnsortedAdapter2 adapter2 = new UnsortedAdapter();
biologicalRhythms.setAdapter(adapter2);
biologicalRhythms.setLayoutManager(new LinearLayoutManager(this));
biologicalRhythms.setHasFixedSize(true);
And in onChange:
adapter.setData(EatAFrog(unsorted));
eatAFrogList = EatAFrog(unsorted);
adapter2.setData1(BiologicalRhythms(unsorted));
biologicalList = BiologicalRhythms(unsorted);
Could you please suggest how I can solve this problem? Thanks for any help.
MyViewModel class:
public class UnsortedViewModel extends AndroidViewModel {
private DatesRepository repository2;
private UnsortedRepository repository;
private SortedRepository repository3;
private LiveData<List<Unsorted>> allUnsorted;
public UnsortedViewModel(#NonNull Application application) {
super(application);
repository3 = new SortedRepository(application);
repository2 = new DatesRepository(application);
repository = new UnsortedRepository(application);
allUnsorted = repository.getAllUnsorted();
}
public LiveData<List<Unsorted>> getUnsortedWhereDateIsAlgo1(String currentDate) throws ExecutionException, InterruptedException{
return repository.getUnsortedWhereDateIs(currentDate);
}
public LiveData<List<Unsorted>> getUnsortedWhereDateIsAlgo2(String currentDate) throws ExecutionException, InterruptedException{
return repository.getUnsortedWhereDateIs(currentDate);
}
MutableLiveData<List<Unsorted>> unsortedWhereDateIsAlgo1 = new MutableLiveData<>();
MutableLiveData<List<Unsorted>> unsortedWhereDateIsAlgo2 = new MutableLiveData<>();
public void insertDate(Dates dates) {
repository2.insertDate(dates);
}
public LiveData<List<Unsorted>> getAllUnsorted() {
return allUnsorted;
}
public void insert(Unsorted data){
repository.insert(data);
}
public void deleteAllUnsorted(){
repository.deleteAllUnsorted();
}
public void deleteWhereDateIs(String currentDate){
repository.deleteWhereDateIs(currentDate);
}
public void insertSorted(Sorted data){
repository3.insertSorted(data);
}
}
Repository:
public class UnsortedRepository {
private UnsortedDao unsortedDao;
private LiveData<List<Unsorted>> allUnsorted;
public UnsortedRepository(Application application){
UnsortedDatabase database = UnsortedDatabase.getInstance(application);
unsortedDao = database.unsortedDao();
allUnsorted = unsortedDao.getAllUnsorted();
}
public LiveData<List<Unsorted>> getUnsortedWhereDateIs(String currentDate)
throws ExecutionException, InterruptedException{
return new
GetUnsortedWhereDateIsAsyncTask(unsortedDao).execute(currentDate).get();
}
private static class GetUnsortedWhereDateIsAsyncTask extends
AsyncTask<String, Void, LiveData<List<Unsorted>>> {
private UnsortedDao unsortedDao;
private GetUnsortedWhereDateIsAsyncTask(UnsortedDao unsortedDao){
this.unsortedDao = unsortedDao;
}
#Override
protected LiveData<List<Unsorted>> doInBackground(String ... strings) {
LiveData<List<Unsorted>> list =
unsortedDao.getUnsortedWhereDateIs(strings[0]);
return list;
}
}
}
Dao:
#Query ("SELECT * FROM Unsorted WHERE date = :currentDate")
LiveData<List<Unsorted>> getUnsortedWhereDateIs (String currentDate);

Your problem is, that you are observing single data source, so you will always have same data in both adapters. You need to add another LiveData inside your viewmodel. Use something like this:
unsortedWhereDateIsAlgo1 : MutableLiveData<List<Unsorted>>()
unsortedWhereDateIsAlgo2 : MutableLiveData<List<Unsorted>>()
and post result of your algorithms into correct LiveData:
fun algo1() {
//some code/operations
unsortedWhereDateIsAlgo1.postValue(result)
}
fun algo2() {
//some different code/operations
unsortedWhereDateIsAlgo2.postValue(result)
}
Next, in your fragment/activity:
viewModel.getUnsortedWhereDateIsAlgo1(currentDate).observe(this, new Observer<List<Unsorted>>() {
#Override
public void onChanged(List<Unsorted> unsorted) {
final UnsortedAdapter adapter = new UnsortedAdapter();
adapter.setData(EatAFrog(unsorted));
eatFrog.setHasFixedSize(true);
eatFrog.setLayoutManager(new LinearLayoutManager(this));
eatFrog.setAdapter(adapter);
}
});
and
viewModel.getUnsortedWhereDateIsAlgo2(currentDate).observe(this, new Observer<List<Unsorted>>() {
#Override
public void onChanged(List<Unsorted> unsorted) {
final UnsortedAdapter adapter2 = new UnsortedAdapter();
adapter2.setData(BiologicalRhythms(unsorted));
biologicalRhythms.setAdapter(adapter2);
biologicalRhythms.setLayoutManager(new LinearLayoutManager(this));
biologicalRhythms.setHasFixedSize(true);
}
});

Related

I trying to do Expandable Recyclerview but have a bug Android/Java

I try to implement expandable RecyclerView as shown in this example :
https://github.com/CodingSTUFF070/Nested-RecyclerView-Inside-Expandable-RecyclerView
But I have bug :
When I implement the same for my app. Steps to reproduce - Click 1st item (Instant Food and Noodles) and scroll to last and click last item (Personal Care) without closing 1st opened item. Now, if you scroll-up and see the child items of 1st parent, you'll see child items of lastly opened parent (Personal Care).
Please tell me how to fix this?
MainActivity:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<DataModel> mList;
private ItemAdapter adapter;
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.main_recyclervie);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mList = new ArrayList<>();
//list1
List<String> nestedList1 = new ArrayList<>();
nestedList1.add("Jams and Honey");
nestedList1.add("Pickles and Chutneys");
nestedList1.add("Readymade Meals");
nestedList1.add("Chyawanprash and Health Foods");
nestedList1.add("Pasta and Soups");
nestedList1.add("Sauces and Ketchup");
nestedList1.add("Namkeen and Snacks");
nestedList1.add("Honey and Spreads");
List<String> nestedList2 = new ArrayList<>();
nestedList2.add("Book");
nestedList2.add("Pen");
nestedList2.add("Office Chair");
nestedList2.add("Pencil");
nestedList2.add("Eraser");
nestedList2.add("NoteBook");
nestedList2.add("Map");
nestedList2.add("Office Table");
List<String> nestedList3 = new ArrayList<>();
nestedList3.add("Decorates");
nestedList3.add("Tea Table");
nestedList3.add("Wall Paint");
nestedList3.add("Furniture");
nestedList3.add("Bedsits");
nestedList3.add("Certain");
nestedList3.add("Namkeen and Snacks");
nestedList3.add("Honey and Spreads");
List<String> nestedList4 = new ArrayList<>();
nestedList4.add("Pasta");
nestedList4.add("Spices");
nestedList4.add("Salt");
nestedList4.add("Chyawanprash");
nestedList4.add("Maggie");
nestedList4.add("Sauces and Ketchup");
nestedList4.add("Snacks");
nestedList4.add("Kurkure");
List<String> nestedList5 = new ArrayList<>();
nestedList5.add("Jams and Honey");
nestedList5.add("Pickles and Chutneys");
nestedList5.add("Readymade Meals");
nestedList5.add("Chyawanprash and Health Foods");
nestedList5.add("Pasta and Soups");
nestedList5.add("Sauces and Ketchup");
nestedList5.add("Namkeen and Snacks");
nestedList5.add("Honey and Spreads");
List<String> nestedList6 = new ArrayList<>();
nestedList6.add("Pasta");
nestedList6.add("Spices");
nestedList6.add("Salt");
nestedList6.add("Chyawanprash");
nestedList6.add("Maggie");
nestedList6.add("Sauces and Ketchup");
nestedList6.add("Snacks");
nestedList6.add("Kurkure");
List<String> nestedList7 = new ArrayList<>();
nestedList7.add("Decorates");
nestedList7.add("Tea Table");
nestedList7.add("Wall Paint");
nestedList7.add("Furniture");
nestedList7.add("Bedsits");
nestedList7.add("Certain");
nestedList7.add("Namkeen and Snacks");
nestedList7.add("Honey and Spreads");
mList.add(new DataModel(nestedList1 , "Instant Food and Noodles"));
mList.add(new DataModel( nestedList2,"Stationary"));
mList.add(new DataModel( nestedList3,"Home Care"));
mList.add(new DataModel(nestedList4 ,"Grocery & Staples"));
mList.add(new DataModel(nestedList5,"Pet Care"));
mList.add(new DataModel(nestedList6,"Baby Care"));
mList.add(new DataModel(nestedList7 ,"Personal Care"));
adapter = new ItemAdapter(mList);
recyclerView.setAdapter(adapter);
}
}
DataModel:
public class DataModel {
private List<String> nestedList;
private String itemText;
private boolean isExpandable;
public DataModel(List<String> itemList, String itemText) {
this.nestedList = itemList;
this.itemText = itemText;
isExpandable = false;
}
public void setExpandable(boolean expandable) {
isExpandable = expandable;
}
public List<String> getNestedList() {
return nestedList;
}
public String getItemText() {
return itemText;
}
public boolean isExpandable() {
return isExpandable;
}
}
ItemAdapter:
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ItemViewHolder> {
private List<DataModel> mList;
private List<String> list = new ArrayList<>();
public ItemAdapter(List<DataModel> mList){
this.mList = mList;
}
#NonNull
#Override
public ItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.each_item , parent , false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, int position) {
DataModel model = mList.get(position);
holder.mTextView.setText(model.getItemText());
boolean isExpandable = model.isExpandable();
holder.expandableLayout.setVisibility(isExpandable ? View.VISIBLE : View.GONE);
if (isExpandable){
holder.mArrowImage.setImageResource(R.drawable.arrow_up);
}else{
holder.mArrowImage.setImageResource(R.drawable.arrow_down);
}
NestedAdapter adapter = new NestedAdapter(list);
holder.nestedRecyclerView.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext()));
holder.nestedRecyclerView.setHasFixedSize(true);
holder.nestedRecyclerView.setAdapter(adapter);
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
model.setExpandable(!model.isExpandable());
list = model.getNestedList();
notifyItemChanged(holder.getAdapterPosition());
}
});
}
#Override
public int getItemCount() {
return mList.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder{
private LinearLayout linearLayout;
private RelativeLayout expandableLayout;
private TextView mTextView;
private ImageView mArrowImage;
private RecyclerView nestedRecyclerView;
public ItemViewHolder(#NonNull View itemView) {
super(itemView);
linearLayout = itemView.findViewById(R.id.linear_layout);
expandableLayout = itemView.findViewById(R.id.expandable_layout);
mTextView = itemView.findViewById(R.id.itemTv);
mArrowImage = itemView.findViewById(R.id.arro_imageview);
nestedRecyclerView = itemView.findViewById(R.id.child_rv);
}
}
}
NestedAdapter:
public class NestedAdapter extends RecyclerView.Adapter<NestedAdapter.NestedViewHolder> {
private List<String> mList;
public NestedAdapter(List<String> mList){
this.mList = mList;
}
#NonNull
#Override
public NestedViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.nested_item , parent , false);
return new NestedViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull NestedViewHolder holder, int position) {
holder.mTv.setText(mList.get(position));
}
#Override
public int getItemCount() {
return mList.size();
}
public class NestedViewHolder extends RecyclerView.ViewHolder{
private TextView mTv;
public NestedViewHolder(#NonNull View itemView) {
super(itemView);
mTv = itemView.findViewById(R.id.nestedItemTv);
}
}
}

Show data in Nested Recyclerview in android

As I fetched and show the dates (see image) as the title of the main recyclerview. I want to show the available slots data instead of the 0 1 2 etc elements. The code is attached below
Url for json data
https://run.mocky.io/v3/c9bd7858-0e41-422f-b1d2-cd490c08583b
AppointmentTimeActivity.java
public class AppointmentTimeActivity extends AppCompatActivity {
SharedPrefManager sharedPrefManager;
Button appointmentTimeButton;
private TextView doctorFullName;
ConstraintLayout constraintLayout;
public static List<List<String>> availableSlots;
RecyclerView rvGroup;
public static ArrayList<String> arrayListGroup;
LinearLayoutManager layoutManagerGroup;
GroupAdapter groupAdapter;
private DoctorScheduleResponse timings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_appointment_time);
getSupportActionBar().setTitle("Appointment time");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
sharedPrefManager = new SharedPrefManager(this);
constraintLayout = findViewById(R.id.constraintLayout);
appointmentTimeButton = findViewById(R.id.book_video_call_appointment_btn);
doctorFullName = findViewById(R.id.doctor_full_name);
rvGroup = findViewById(R.id.rv_group);
String docName = getIntent().getStringExtra("doctorFullName");
doctorFullName.setText(docName);
arrayListGroup = new ArrayList<>();
fetchAndShowAppointmentsTime();
}
private void fetchAndShowAppointmentsTime() {
String id = String.valueOf(SpecialityActivity.doctorID);
Call<DoctorScheduleResponse> call = RetrofitClient.getInstance().getMyInterface().getAppointmentTime("Bearer " + sharedPrefManager.getAccessToken(), id);
call.enqueue(new Callback<DoctorScheduleResponse>() {
#Override
public void onResponse(#NotNull Call<DoctorScheduleResponse> call, #NotNull Response<DoctorScheduleResponse> response) {
arrayListGroup = new ArrayList<>();
if (response.isSuccessful()) {
assert response.body() != null;
for (List<Slot> slots : response.body().getSlot()) {
for (Slot slot : slots) {
arrayListGroup.add(slot.getScheduleDate());
}
}
groupAdapter = new GroupAdapter(AppointmentTimeActivity.this, response.body().getSlot());
layoutManagerGroup = new LinearLayoutManager(getApplicationContext());
rvGroup.setLayoutManager(layoutManagerGroup);
rvGroup.setAdapter(groupAdapter);
}
}
#Override
public void onFailure(#NotNull Call<DoctorScheduleResponse> call, #NotNull Throwable t) {
Toast.makeText(getBaseContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
DoctorScheduleResponse.java
public class DoctorScheduleResponse {
#SerializedName("slot")
#Expose
private List<List<Slot>> slot = null;
public List<List<Slot>> getSlot() {
return slot;
}
public void setSlot(List<List<Slot>> slot) {
this.slot = slot;
}
}
GroupAdater.java
public class GroupAdapter extends RecyclerView.Adapter<GroupAdapter.ViewHolder> {
private Activity activity;
ArrayList<String> arrayListGroup, arrayListMember;
LinearLayoutManager linearLayoutManager;
SharedPrefManager sharedPrefManager;
List<List<Slot>> slotsList;
public GroupAdapter(Activity activity, ArrayList<String> arrayListGroup) {
this.activity = activity;
this.arrayListGroup = arrayListGroup;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_slot_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.dummyTV.setText(arrayListGroup.get(position));
arrayListMember = new ArrayList<>();
sharedPrefManager = new SharedPrefManager(activity);
for (int i = 0; i < 5; i++) {
arrayListMember.add(String.valueOf(i));
}
CustomAdapter customAdapter = new CustomAdapter(arrayListMember);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(activity);
holder.rvMember.setLayoutManager(linearLayoutManager);
holder.rvMember.setAdapter(customAdapter);
}
#Override
public int getItemCount() {
return arrayListGroup.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView dummyTV;
RecyclerView rvMember;
public ViewHolder(#NonNull View itemView) {
super(itemView);
dummyTV = itemView.findViewById(R.id.dummyTextView);
rvMember = itemView.findViewById(R.id.rv_member);
}
}
}
CustomAdapter.java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.SlotsViewHolder> {
ArrayList<String> slots;
public CustomAdapter(ArrayList<String> slots) {
this.slots = slots;
}
#NonNull
#Override
public SlotsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.available_slots_list, parent, false);
return new CustomAdapter.SlotsViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SlotsViewHolder holder, int position) {
holder.tvSlots.setText(slots.get(position));
}
#Override
public int getItemCount() {
return slots.size();
}
public class SlotsViewHolder extends RecyclerView.ViewHolder {
TextView tvSlots;
public SlotsViewHolder(#NonNull View itemView) {
super(itemView);
tvSlots = itemView.findViewById(R.id.tv_slots);
}
}
}
Nested recycler view will be more complex in terms of memory. So you can achieve same UI with different approach.
You should try with single recycler view with dynamic layout binding.
Example: For single item of recycler view, there will be a header(for date) and a viewgroup(may be linear layout) then bind any no. of child views inside that linear layout.
The problem is in GroupAdater.java. Inside onBindViewHolder method you are adding the value of loop variable to your list that you pass to your nested recycler view adaptor.
for (int i = 0; i < 5; i++) {
arrayListMember.add(String.valueOf(i));
}
You have to add the correct date from arrayListGroup object.

Androidx RecycleView Not showing items with parse server

This is my adapter for recycle view
CategoryAdapter Class
public class CategoryRAdapter extends RecyclerView.Adapter<CategoryRAdapter.MyViewHolder> {
private Context mcontext;
private List<Food> mData;
RequestOptions option;
public CategoryRAdapter(Context mcontext, List<Food> mData) {
this.mcontext = mcontext;
this.mData = mData;
option = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_row, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Food current = mData.get(position);
holder.tv_Name.setText(current.getName());
holder.tv_Rating.setText(current.getRating());
holder.tv_Descip.setText(current.getDescrip());
holder.tv_Category.setText(current.getCateg());
Glide.with(mcontext).load(mData.get(position).getImages()).apply(option).into(holder.img_Thumbnail);
}
#Override
public int getItemCount() {
return mData.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_Name;
TextView tv_Rating;
TextView tv_Descip;
TextView tv_Category;
ImageView img_Thumbnail;
public MyViewHolder(View itemView) {
super(itemView);
tv_Name = itemView.findViewById(R.id.food_name);
tv_Rating = itemView.findViewById(R.id.rating);
tv_Descip = itemView.findViewById(R.id.desc);
tv_Category = itemView.findViewById(R.id.category);
img_Thumbnail = itemView.findViewById(R.id.thumbnail);
}
}
}
This is my model
Food Class
public class Food {
String Name;
String Images;
String Descrip;
String Rating;
String Categ;
public Food() {
}
public Food(String name, String images, String descrip, String rating, String categ) {
this.Name = name;
this.Images = images;
this.Descrip = descrip;
this.Rating = rating;
this.Categ = categ;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getImages() {
return Images;
}
public void setImages(String images) {
Images = images;
}
public String getDescrip() {
return Descrip;
}
public void setDescrip(String descrip) {
Descrip = descrip;
}
public String getRating() {
return Rating;
}
public void setRating(String rating) {
Rating = rating;
}
public String getCateg() {
return Categ;
}
public void setCateg(String categ) {
Categ = categ;
}
}
My mian activity
CategoryActivity Class
public class CategoriaActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Food> dbObjects;
private RecyclerView.Adapter adapter;
private AlertDialog.Builder dialogBuilder;
private AlertDialog dialog;
TextView l_nombre,l_precio;
Button l_finalizar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_categoria);
recyclerView = findViewById(R.id.recycle_id);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
dbObjects = new ArrayList<>();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Category");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objList, ParseException e) {
if (e == null) {
for (ParseObject obj : objList) {
Food food = new Food();
food.setName(obj.getString("Name"));
food.setDescrip(obj.getString("Descrip"));
food.setRating(obj.getString("Rating"));
food.setCateg(obj.getString("Categ"));
food.setImages(obj.getString("Images"));
dbObjects.add(food);
}
} else {
FancyToast.makeText(CategoriaActivity.this, "Error: " + e.getMessage(), FancyToast.LENGTH_SHORT, FancyToast.ERROR, true).show();
}
}
});
adapter = new CategoryRAdapter(this, dbObjects);
recyclerView.setAdapter(adapter);
FloatingActionButton fab = findViewById(R.id.shoppingFlot);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
carritopop();
}
});
}
private void carritopop() {
dialogBuilder = new AlertDialog.Builder(this);
View view = getLayoutInflater().inflate(R.layout.pop_cart,null);
l_finalizar = view.findViewById(R.id.l_finalizar);
l_finalizar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pago();
}
});
dialogBuilder.setView(view);
dialog = dialogBuilder.create();
dialog.show();
}
private void pago() {
Intent intent = new Intent(CategoriaActivity.this, PagoActivity.class);
startActivity(intent);
}
}
I dont know whats wrong with the code, the recycle view aint working, it aint showing any items, i would really appreciate if someone could help me out and notice something wrong in my code
Call adapter.notifyDataSetChanged() in your query done callback, this will notify the adapter that the list has changed. This is happening because when you set the adapter, the list was empty as the query was running in background. Once it completes, you have to tell the adapter that new data has been added to list:
if (e == null) {
for (ParseObject obj : objList) {
...
}
adapter.notifyDataSetChanged();
}
Also, create your adapter before you send the query otherwise it may result in NullPointerException in case data is loaded before the next statement executes (highly unlikely but never hurts to be safe).
dbObjects = new ArrayList<>();
adapter = new CategoryRAdapter(this, dbObjects);
ParseQuery<ParseObject> query = ParseQuery.getQuery("Category");
I recommend you to use RxJava2 to user asynchronous methods, it's awesome... And about the problem, maybe your data is not ready when you're already creating the adapter with the ArrayList.
Try to move the recyclerView.setAdapter() to inside the FindCallback after create the Food Objects.

Recyclerview not showing data serializable

I'm trying to list data from serializable object but it doesn't work show nothing.
I am listing information from a recyclerview with serialized object. When passing to another activity, the recyclerview does not show any data.
Sorry about my english.
MainActivity
private void onOrderProduct() {
bOrder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cart cart = new Cart();
cart.setComida(tvTitle.getText().toString());
cart.setPreco(tvTotal.getText().toString());
cart.setQuantidade(tvQtd.getText().toString());
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("cart", cart);
startActivity(intent);
}
});
}
SecondActivity
public class SecondActivity extends AppCompatActivity {
RecyclerView rvCart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
rvCart = (RecyclerView) findViewById(R.id.tela5recycler_view);
rvCart.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(this);
rvCart.setLayoutManager(manager);
if (getIntent().getSerializableExtra("cart") != null) {
Intent intent = getIntent();
Cart cart = (Cart) intent.getSerializableExtra("cart");
ArrayList<Cart> eList = new ArrayList<>() cart;
Adapter adapter =new Adapter(getApplicationContext(), eList );
rvCart.setAdapter(adapter);
}
}
}
Adapter
public class Adapter extends RecyclerView.Adapter<Adapter.ItemViewHolder> {
private Context context;
private ArrayList<Cart> itemList;
public Adapter(Context context, ArrayList<Cart> itemList){
this.context = context;
this.itemList = itemList;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.from(parent.getContext())
.inflate(R.layout.adapter_card, parent, false);
ItemViewHolder itemViewHolder = new ItemViewHolder(view);
return itemViewHolder;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
Cart item = itemList.get(position);
holder.tvQtdcard.setText(item.getQuantidade());
holder.tvComidacard.setText(item.getComida());
holder.tvPrecocard.setText(item.getPreco());
}
#Override
public int getItemCount() {
if(itemList != null){
return itemList.size();
}
return 0;
}
public static class ItemViewHolder extends RecyclerView.ViewHolder{
public CardView cvItem;
public TextView tvQtdcard, tvComidacard, tvPrecocard;
public ItemViewHolder(View itemView) {
super(itemView);
cvItem = (CardView)itemView.findViewById(R.id.tela1_1_1_1_1card);
tvQtdcard = (TextView)itemView.findViewById(R.id.tela5qtdcard);
tvComidacard = (TextView)itemView.findViewById(R.id.tela5comidacard);
tvPrecocard = (TextView)itemView.findViewById(R.id.tela5precocard);
}
}
}
Cart.class Serializable
import java.io.Serializable;
public class Cart implements Serializable{
private static final long serialVersionUID = 42L;
private String comida;
private String quantidade;
private String preco;
public String getComida() {
return comida;
}
public void setComida(String comida) {
this.comida = comida;
}
public String getQuantidade() {
return quantidade;
}
public void setQuantidade(String quantidade) {
this.quantidade = quantidade;
}
public String getPreco() {
return preco;
}
public void setPreco(String preco) {
this.preco = preco;
}
public String toString(){
return comida;
}
}
You are missing adapter.notifyDataSetChanged() after and you are passing empty arraylist eList
ArrayList<Cart> eList = new ArrayList<>();
eList.add(cart);
Adapter adapter =new Adapter(getApplicationContext(), eList );
rvCart.setAdapter(adapter);
To pass the serialized object
Solution 1 (Hackytack solution)
public class CardListHolder implements Serializable{
private ListcardList=new ArrayList<>();
public List<Card>getCardList(){
return cardList;
}
public void setCardList(List<Card> cardList){
this.cardList=cardList;
}
}
Use this holder object to pass the list of card
Solution 2
Implement Parcelable for Card object, it can pass list of card but it is little bit complex to understand. Try www.parcelabler.com to auto generate the Parceable class for Card.

RecyclerView isn't attached to Adapter

I have this strage error. I'm downloading data from API and I want to print it in RecyclerView nested in Fragment called ListFragment. This fragment is one of three which I use in ViewPager. ViewPager works fine. For now, I want to display only two textViews. Layout for them has name single_data_layout. List<Feature> features is my DataResponse. Project builds normaly without issues and I receive in Log that "Data is successfully downloaded". When I run app in DebugMode I get message that my RecyclerView isn't attached to adapter. Any ideas?
ApiClient:
public interface ApiClient {
#GET("/query?format=geojson&starttime&minsig=700")
Call<DataResponse> getData();
}
ApiClientFactory:
public class ApiClientFactory {
public static final String baseURL = "https://earthquake.usgs.gov/fdsnws/event/1/";
public ApiClient createApiClient(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(ApiClient.class);
}
}
DataAdapter:
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataViewHolder> {
private List<Feature> features;
private ListFragment listFragment;
private Context context;
private LayoutInflater inflater;
public DataAdapter(List<Feature> features) {
this.features = features;
}
#Override
public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater = LayoutInflater.from(context);
View contractView = inflater.inflate(R.layout.single_data_layout, parent, false);
return new DataViewHolder(contractView);
}
#Override
public void onBindViewHolder(DataViewHolder holder, int position) {
holder.place.setText(features.get(position).getProperties().getPlace());
holder.alert.setText(features.get(position).getProperties().getAlert());
}
#Override
public int getItemCount() {
return features.size();
}
public static class DataViewHolder extends RecyclerView.ViewHolder {
private final TextView place;
private final TextView alert;
public DataViewHolder(View view) {
super(view);
place = (TextView) view.findViewById(R.id.place_text_view);
alert = (TextView) view.findViewById(R.id.alert_text_view);
}
}
}
ListFragment:
public class ListFragment extends Fragment {
private RecyclerView recyclerView;
private static final String TAG = ListFragment.class.getSimpleName();
private ApiClient apiClient;
private List<Feature> features;
private RecyclerView.LayoutManager layoutManager;
private DataAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
getData();
return view;
}
private void getData() {
apiClient = new ApiClientFactory().createApiClient();
apiClient.getData().enqueue(new Callback<DataResponse>() {
#Override
public void onResponse(Call<DataResponse> call, Response<DataResponse> response) {
if (response.isSuccessful()) {
features = response.body().getFeatures();
adapter = new DataAdapter(features);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
}
Log.d(TAG, "Data successfully downloaded");
}
#Override
public void onFailure(Call<DataResponse> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
}
You should change the way you inflate the layout. This should do the trick.
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataViewHolder> {
private List<Feature> features;
public DataAdapter(List<Feature> features) {
this.features = features;
}
#Override
public DataAdapter.DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_data_layout, parent, false);
return new DataViewHolder(view);
}
#Override
public void onBindViewHolder(DataViewHolder holder, int position) {
holder.place.setText(features.get(position).getProperties().getPlace());
holder.alert.setText(features.get(position).getProperties().getAlert());
}
#Override
public int getItemCount() {
return features.size();
}
public static class DataViewHolder extends RecyclerView.ViewHolder {
private final TextView place;
private final TextView alert;
public DataViewHolder(View view) {
super(view);
place = (TextView) view.findViewById(R.id.place_text_view);
alert = (TextView) view.findViewById(R.id.alert_text_view);
}
}
}
I see that the adapter class don't have a context , I guess if you add to the adapter constructor Context c as a second parameter your problem will be solved
try to replase
public DataAdapter(List<Feature> features) {
this.features = features;
}
by this
public DataAdapter(List<Feature> features, Context c) {
this.features = features;
this.context = c;
}
and replace this line in the fragment class
adapter = new DataAdapter(features);
by this
adapter = new DataAdapter(features,getActivity());
hope this will help you :)

Categories

Resources