RecyclerView shows wrong views - android

RecyclerView shows first items after some correct items. And one of incorrect items can change own data several times... It is really strange and i dont know why, in another app i wrote the same code and all works nice. I tried to find the resolve, but did not found nothing what helps. You can see video to understand what is going on.
video
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable
ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_car_list, container, false);
mRecyclerView = view.findViewById(R.id.car_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
private class CarHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
private Car mCar;
public CarHolder(#NonNull final View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mProducerTextView = itemView.findViewById(R.id.producerCardTextView);
mModelTextView = itemView.findViewById(R.id.modelCardTextView);
mPriceTextView = itemView.findViewById(R.id.priceCardTextView);
}
public void bind(Car car) {
mCar = car;
mProducerTextView.setText(getString(R.string.producer_params,
mCar.getProducer()));
mModelTextView.setText(getString(R.string.model_params,
mCar.getModel()));
mPriceTextView.setText(getString(R.string.price_params,
mCar.getPrice()));
}
#Override
public void onClick(View v) {
mListCallBack.onCarSelected(mCar);
}
}
private class CarAdapter extends RecyclerView.Adapter<CarHolder> {
private List<Car> mCars;
public CarAdapter(List<Car> cars) {
mCars = cars;
}
#NonNull
#Override
public CarHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
View view = inflater.inflate(R.layout.list_item_car, viewGroup, false);
return new CarHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CarHolder carHolder, int i) {
Car car = mCars.get(i);
carHolder.bind(car);
}
#Override
public int getItemCount() {
return mCars.size();
}
public void setCars(List<Car> cars) {
this.mCars = cars;
}
}
public void updateUI(){
List<Car> cars = CarLab.getCarLab(getActivity()).getCars();
if (mAdapter == null) {
mAdapter = new CarAdapter(cars);
mRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.setCars(cars);
mAdapter.notifyDataSetChanged();
}
}

may be you can try your RecyclerView not to recyle items using:
mRecyclerView.getRecycledViewPool().setMaxRecycledViews(0,0);
in your onCreate() method below mRecyclerView.setLayoutManager(...);

The problem occurs when you use the field variable mCar (which manipulates by all bind events) to update your viewHoleder, just simply use the car variable you pass to the bind to update views.
The other problem with your code is inside onClick, again you should not use the field variable mCar, instead get the item it needs like this:
#Override
public void onClick(View v) {
Car car = mCars.get(getAdapterPosition());
mListCallBack.onCarSelected(car);
}

Related

android simple animation is skipping on older device

I have a RecyclerView with multiple TextViews and a Button. The button triggers an animation like the gif below:
I am doing this by creating a RecyclerView.Adapter and creating an OnClickListener like so:
public class recyclerViewAdapter extends RecyclerView.Adapter<recyclerViewAdapter.ViewHolder> {
private ArrayList<MyObject> objects;
// constructor and other stuff ...
public void setDefaultRequestBtnClickListener(View.OnClickListener defaultRequestBtnClickListener) {
this.defaultRequestBtnClickListener = defaultRequestBtnClickListener;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
MyObject object = objects.get(position);
if (object.getRequestBtnClickListener() != null) {
holder.Btn.setOnClickListener(object.getRequestBtnClickListener());
}else {
holder.Btn.setOnClickListener(defaultRequestBtnClickListener);
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView value;
TextView currentVal;
TextView Btn;
ConstraintLayout parent;
public ViewHolder(#NonNull View itemView) {
super(itemView);
value = itemView.findViewById(R.id.totalPrice);
currentVal = itemView.findViewById(R.id.checkBtn);
Btn = itemView.findViewById(R.id.animateBtn);
parent = itemView.findViewById(R.id.parent);
}
public void bind(final OnMyClickListener listener) {
parent.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onMyClick(v, getLayoutPosition());
}
});
}
}
public interface OnMyClickListener{
void onMyClick(View view, int position);
}
}
this creates and binds a view holder in a recycler view to the TextViews and buttons. At the moment a user has to click the element to activate the Btn and animation. The below is the fragment that is initiating the adapter:
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.frag_object_layout, container, false);
final RecyclerView recyclerView = rootView.findViewById(R.id.list);
final ArrayList<MyObject> objects = MyObject.getTestingList();
final recyclerViewAdapter adapter = new recyclerViewAdapter(objects, getContext());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter.setDefaultRequestBtnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
recyclerViewAdapter.ViewHolder holder = (recyclerViewAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(Position);
if (holder != null) {
if (holder.value.getAlpha() == 0.0f) {
holder.value.animate().alpha(1.0f).setDuration(500);
holder.value.animate().translationY(-38).setDuration(1000);
holder.checkValue.animate().translationY(38).setDuration(1000);
} else {
holder.value.animate().alpha(0.0f).setDuration(500);
holder.value.animate().translationY(0).setDuration(500);
holder.checkValue.animate().translationY(0).setDuration(500);
}
}
}
});
adapter.setOnMyClickListener(new recyclerViewAdapter.OnMyClickListener() {
#Override
public void onMyClick(View view, int pos) {
Position = pos;
holder = (recyclerViewAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(Position);
}
});
return rootView;
}
}
This is all working great on an emulator, but on an older device the animation is skipping and the views go directly to their final position. Why is that? I checked the processing time and it is below the 16ms threshold.
How can I improve this?
(Posting the whole code is difficult here. ask for code and I will update the question)
The issue here is that I was doing this programmatically. For some reason, if I call Animator object and pass anim xml files then the animation works (on old device). Does anyone know why?

simple animation is skipping on older devices

I have a RecyclerView with multiple TextViews and a Button. The button triggers an animation like the gif below:
I am doing this by creating a RecyclerView.Adapter and creating an OnClickListener like so:
public class recyclerViewAdapter extends RecyclerView.Adapter<recyclerViewAdapter.ViewHolder> {
private ArrayList<MyObject> objects;
// constructor and other stuff ...
public void setDefaultRequestBtnClickListener(View.OnClickListener defaultRequestBtnClickListener) {
this.defaultRequestBtnClickListener = defaultRequestBtnClickListener;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
MyObject object = objects.get(position);
if (object.getRequestBtnClickListener() != null) {
holder.Btn.setOnClickListener(object.getRequestBtnClickListener());
}else {
holder.Btn.setOnClickListener(defaultRequestBtnClickListener);
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView value;
TextView currentVal;
TextView Btn;
ConstraintLayout parent;
public ViewHolder(#NonNull View itemView) {
super(itemView);
value = itemView.findViewById(R.id.totalPrice);
currentVal = itemView.findViewById(R.id.checkBtn);
Btn = itemView.findViewById(R.id.animateBtn);
parent = itemView.findViewById(R.id.parent);
}
public void bind(final OnMyClickListener listener) {
parent.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onMyClick(v, getLayoutPosition());
}
});
}
}
public interface OnMyClickListener{
void onMyClick(View view, int position);
}
}
this creates and binds a viewholder in a recyclerview to the TextViews and buttons. At the moment a user has to click the element to activate the Btn and animation. The below is the Fragment that is initiating the adapter:
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.frag_object_layout, container, false);
final RecyclerView recyclerView = rootView.findViewById(R.id.list);
final ArrayList<MyObject> objects = MyObject.getTestingList();
final recyclerViewAdapter adapter = new recyclerViewAdapter(objects, getContext());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter.setDefaultRequestBtnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
recyclerViewAdapter.ViewHolder holder = (recyclerViewAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(Position);
if (holder != null) {
if (holder.value.getAlpha() == 0.0f) {
holder.value.animate().alpha(1.0f).setDuration(500);
holder.value.animate().translationY(-38).setDuration(1000);
holder.checkValue.animate().translationY(38).setDuration(1000);
} else {
holder.value.animate().alpha(0.0f).setDuration(500);
holder.value.animate().translationY(0).setDuration(500);
holder.checkValue.animate().translationY(0).setDuration(500);
}
}
}
});
adapter.setOnMyClickListener(new recyclerViewAdapter.OnMyClickListener() {
#Override
public void onMyClick(View view, int pos) {
Position = pos;
holder = (recyclerViewAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(Position);
}
});
return rootView;
}
}
This is all working great on an emulator, but on an older device the animation is skipping and the views go directly to their final position. Why is that? I checked the processing time and it is below the 16ms threshold.
How can I improve this?
(Posting the whole code is difficult here. ask for code and I will update the question)

Why RecylerView.notifyDataSetChanged() stop working after adding Navigation Components?

I implemented Navigation from Android Jetpack, and then ALL RecyclerViews in my app stopped updating after the data changing. In debug mode I saw that datas really changed and notifyDataSetChanged() is invoked, but RVs actually not updated (new items not added).
I've tried to use other methods, such as notifyItemInserted() and so on. Tried to notify the adapter outside. Nothing helps.
Fragment:
...
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.profnastil_fragment, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
...
ImageButton addRoofBtn = view.findViewById(R.id.roof_add_btn);
addRoofBtn.setOnClickListener(v -> {
...
Square roof = new Square(width, height);
mViewModel.addRoof(roof);
});
mViewModel = ViewModelProviders.of(this).get(ProfnastilViewModel.class);
mProfnastilAdapter = new SquaresAdapter(mViewModel, SquaresAdapter.SQUARE_TYPE_ROOF);
RecyclerView roofRv = view.findViewById(R.id.roof_list);
RecyclerView.LayoutManager wallsLayoutManager = new LinearLayoutManager(getContext());
roofRv.setLayoutManager(wallsLayoutManager);
roofRv.setHasFixedSize(true);
roofRv.setAdapter(mProfnastilAdapter);
mViewModel.getRoofs().observe(this, roofs -> mProfnastilAdapter.setSquares(roofs));
}
Adapter:
...
public SquaresAdapter(SquareViewModelBase model, String squareType) {
mModel = model;
mSquares = new ArrayList<>();
setHasStableIds(true);
mSquareType = squareType;
}
public static class SquareHolder extends RecyclerView.ViewHolder {
View view;
TextView heightText;
TextView widthText;
TextView squareText;
private SquareHolder(#NonNull View itemView) {
super(itemView);
view = itemView;
heightText = itemView.findViewById(R.id.square_height);
widthText = itemView.findViewById(R.id.square_width);
squareText = itemView.findViewById(R.id.result_square);
}
}
#Override
public int getItemCount() {
if (mSquares == null) return 0;
return mSquares.size();
}
#Override
public long getItemId(int position) {
return position;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_square, parent, false);
return new SquareHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, final int position) {
final Square square = mSquares.get(position);
SquareHolder vh = (SquareHolder) viewHolder;
vh.heightText.setText(StringUtils.format(square.getHeight()));
vh.widthText.setText(StringUtils.format(square.getWidth()));
vh.squareText.setText(StringUtils.format(square.getSquare()));
vh.view.findViewById(R.id.item_del_btn).setOnClickListener(v -> {
mModel.removeSquare(square, mSquareType);
});
}
public void setSquares(List<Square> newSquares) {
mSquares.clear();
mSquares.addAll(newSquares);
notifyDataSetChanged();
}
ViewModel:
...
private MutableLiveData<List<Square>> mRoofs = new MutableLiveData<>();
public void addRoof(Square roof) {
List<Square> roofs = mRoofs.getValue();
if (roofs == null) roofs = new ArrayList<>();
roofs.add(roof);
mRoofs.setValue(roofs);
}
Before I implemented the Navigation graph, everything worked correctly. What happens and how to make it work?
In the end adding view.requireLayout() at the Fragment helped me:
mViewModel.getRoofs().observe(this, roofs -> {
mProfnastilAdapter.setSquares(roofs));
view.requireLayout();
};
But I still don't understand what happened and why it helped me =)
I will be grateful if someone will explain to me.

Recycle view not showing items when I start the app but after going to another fragment and back it works

I have to set up a recycle view inside a fragment. The problem is that when I start the app it shows nothing but if i switch to another fragment and go back all items are there. If i start the app and try to scroll through a the recycle view the first item and the last one will load. I tried searching for an answer but there is nothing useful. I mention i just started working in Android Studio.
That's the fragment code
public class Main_fragment extends Fragment {
TextView titleText;
ArrayList<String> titles = new ArrayList<>();
// Access it from anywhere
static String FoodChoiceVar = "All food"; // Value set for test only. Maybe make an ENUM instead?
public Main_fragment() {
// Needed empty constructor.
}
// Don't edit this method as you won't be able tu use "R".
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
titles.add("Breakfast");titles.add("Morning Snack");titles.add("Lunch");titles.add("AfterNoon Snack");titles.add("Dinner"); titles.add("Night Snack");
}
//Use this instead.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_fragment, container, false);
final FragmentActivity c = getActivity();
titleText = view.findViewById(R.id.textViewFoodType);
titleText.setText(FoodChoiceVar + "| MENU");
RecyclerView recyclerView = view.findViewById(R.id.fragmentRecycleView);
LinearLayoutManager layoutManager = new LinearLayoutManager(c);
recyclerView.setLayoutManager(layoutManager);
ViewAdapter adapter = new ViewAdapter(c,titles);
recyclerView.setHasFixedSize(false);
recyclerView.setAdapter(adapter);
return view;
}
The ViewAdapter
public class ViewAdapter extends RecyclerView.Adapter<FoodMenuViewHolder> {
private LayoutInflater layoutInflater;
private List<String> titleData;
public ViewAdapter (Context context,List<String> titleData){
this.layoutInflater = LayoutInflater.from(context);
this.titleData = titleData;
}
#NonNull
#Override
public FoodMenuViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = layoutInflater.inflate(R.layout.layout_menu_item,viewGroup,false);
FoodMenuViewHolder holder = new FoodMenuViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull FoodMenuViewHolder foodMenuViewHolder, int i) {
String title = titleData.get(i);
foodMenuViewHolder.titleText.setText(title);
}
#Override
public int getItemCount() {
return titleData.size();
}
}
The view holder
public class FoodMenuViewHolder extends RecyclerView.ViewHolder {
public TextView titleText;
public FoodMenuViewHolder(#NonNull View itemView) {
super(itemView);
titleText = itemView.findViewById(R.id.ItemText);
}
}
I have captured 2 short videos to show what is happening
https://drive.google.com/file/d/17wvlhPUT5R0SN38C2TbgBv_AP8awQUI3/view?usp=sharing
https://drive.google.com/file/d/1LJ0Xg4p8Q4a4nyGPSHdVQhBlYOYYi1Pv/view?usp=sharing
I think that your adapter it's losing itself, so try to get the context for layout inflater from viewgroup in onCreateViewHolder.
this:
public FoodMenuViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new FoodMenuViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_menu_item, viewGroup, false);
}
And to avoid anoying error, put a execption in getItemCount().
This:
#Override
public int getItemCount() {
if(titleData != null) {
return titleData.size();
} else {
return 0;
}
}
And try to use context instead of Fragment Activity
final FragmentActivity c = getActivity();
to
final Context c = getContext();

Adding item to a recyclerview from dialog within a fragment class.?

I have a fragment which must contains two recycler views. The view looks like follows. i need to add an item to the bottom recyclerview from a dialog. L'll post my code for the adapter class and xml. Please guide me to achieve this, a sample or a code is more than welcome.
I've tried to pass the data from the dialog to the second recyclerview but it does not show the added item. Tell me anything i'm doing wrong here. Nothing i tried worked out to update my second recyclerview... :/
My Fragment Class
public class ReceiptFragment extends Fragment { //implements ContReceiptsAdapter.ItemOnClickListener
RecyclerView rv_rceipts, rv_addpayments;
RecyclerView.Adapter mContReceiptsAdapter,mAddPaymentsAdapter;
RecyclerView.LayoutManager mLayoutManager1,mLayoutManager2;
View receipts_view;
private Context mContext;
ContReceiptsAdapter contReceiptsAdapter;
AddPaymentsAdapter addPaymentsAdapter;
//-- items in detailed dialog here
private ArrayList<Contract> contracts;
private ArrayList<AddPayments> payments;
private View linearLayout;
public View mRootView;
public ReceiptFragment() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
receipts_view = inflater.inflate(R.layout.fragment_receipt, container, false);
BuildReceiptsRV();
BuildAddedPaymentsRV();
// for setting the first item as default in the list
// onItemClicked(0);
return receipts_view;
}
private void BuildReceiptsRV() {
rv_rceipts = receipts_view.findViewById(R.id.rv_tobe_added);
rv_rceipts.setHasFixedSize(true);
rv_rceipts.setItemAnimator(new DefaultItemAnimator());
mLayoutManager1 = new LinearLayoutManager(getActivity());
rv_rceipts.setLayoutManager(mLayoutManager1);
mContReceiptsAdapter = new ContReceiptsAdapter(getActivity(), ApplicationClass.contractList);
rv_rceipts.setAdapter(mContReceiptsAdapter);
}
private void BuildAddedPaymentsRV() {
rv_addpayments = receipts_view.findViewById(R.id.rv_added);
rv_addpayments.setHasFixedSize(true);
rv_addpayments.setItemAnimator(new DefaultItemAnimator());
mLayoutManager2 = new LinearLayoutManager(getActivity());
rv_addpayments.setLayoutManager(mLayoutManager2);
mAddPaymentsAdapter = new AddPaymentsAdapter(getActivity(),ApplicationClass.paymentList);
rv_addpayments.setAdapter(mAddPaymentsAdapter);
}
//change when click on change on item added to second rv
private void changeLayoutRV() {
linearLayout = mRootView.findViewById(R.id.rv_tobe_added);
if (linearLayout.getVisibility() == View.GONE) {
linearLayout.setVisibility(View.VISIBLE);
} else {
linearLayout.setVisibility(View.GONE);
}
}
}
My Adapter for the First Recyclerview
public class ContReceiptsAdapter extends RecyclerView.Adapter<ContReceiptsAdapter.ReceiptsViewHolder> {
// private static Dialog AddItemDialog;
private ArrayList<Contract> contracts;
private ArrayList<AddPayments> payments = new ArrayList<>();
Context mContext;
String inPending;
//for the details dialog
EditText et_number, contract_id_val, product_type_val, mobile_number_ADialog, et_amount_add;
// ImageView btn_add_item;
//--to set to add item dialog
public TextView contract_number, vehicle_number, contract_number_ADialog, vehicle_number_ADialog;
CheckBox checkbox_pending;
public ContReceiptsAdapter(Context context, ArrayList<Contract> contractList) {
contracts = contractList;
mContext = context;
}
public class ReceiptsViewHolder extends RecyclerView.ViewHolder {
TextView tv_contract, tvVehicleN, tvContractType;
ImageView btn_add_item;
LinearLayout detailsLayout;
public ReceiptsViewHolder(#NonNull final View itemView) {
super(itemView);
detailsLayout = itemView.findViewById(R.id.add_details_item_id);
tv_contract = itemView.findViewById(R.id.tv_contract);
tvVehicleN = itemView.findViewById(R.id.tvVehicleN);
tvContractType = itemView.findViewById(R.id.tvContractType);
btn_add_item = itemView.findViewById(R.id.btn_add_item);
}
}
#NonNull
#Override
public ContReceiptsAdapter.ReceiptsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.receipt_tobe_added_rv_item, viewGroup, false);
final ReceiptsViewHolder receiptsViewHolder = new ReceiptsViewHolder(view);
//dialog ini
// ShowDetails();
final Dialog detailedDialog = new Dialog(this.mContext);
detailedDialog.setContentView(R.layout.fragment_details);
receiptsViewHolder.detailsLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//click view dto show the detaileds view of the list item
contract_number = detailedDialog.findViewById(R.id.contract_id_val);
vehicle_number = detailedDialog.findViewById(R.id.vehicle_num_val);
contract_number.setText(contracts.get(receiptsViewHolder.getAdapterPosition()).getContractNumber());
vehicle_number.setText(contracts.get(receiptsViewHolder.getAdapterPosition()).getVehicleNumber());
detailedDialog.show();
detailedDialog.setCancelable(true);
// mListener.onItemClicked(contracts.indexOf(v.getTag()));
}
});
return receiptsViewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ContReceiptsAdapter.ReceiptsViewHolder viewHolder, int i) {
viewHolder.itemView.setTag(contracts.get(i));
// Contract currentItem = contracts.get(i);
viewHolder.tv_contract.setText(contracts.get(i).getContractNumber());
viewHolder.tvVehicleN.setText(contracts.get(i).getVehicleNumber());
viewHolder.tvContractType.setText(contracts.get(i).getContractType());
final Dialog AddItemDialog = new Dialog(mContext);
AddItemDialog.setContentView(R.layout.fragment_add_receipt);
viewHolder.btn_add_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ShowDetails();7
contract_number_ADialog = AddItemDialog.findViewById(R.id.contract_id_val_add);
contract_number_ADialog.setText(contracts.get(viewHolder.getAdapterPosition()).getContractNumber());
vehicle_number_ADialog = AddItemDialog.findViewById(R.id.product_type_val_add);
vehicle_number_ADialog.setText(contracts.get(viewHolder.getAdapterPosition()).getVehicleNumber());
mobile_number_ADialog = AddItemDialog.findViewById(R.id.et_number_add);
mobile_number_ADialog.setText(contracts.get(viewHolder.getAdapterPosition()).getMobileNumber());
checkbox_pending = AddItemDialog.findViewById(R.id.checkbox_pending_add);
checkbox_pending.setChecked(Boolean.parseBoolean(contracts.get(viewHolder.getAdapterPosition()).getPendingState()));
Button btn_cancel_receipt = AddItemDialog.findViewById(R.id.btn_cancel_receipt);
Button btn_add_receipt = AddItemDialog.findViewById(R.id.btn_add_receipt);
et_amount_add = AddItemDialog.findViewById(R.id.et_amount_add);
AddItemDialog.show();
AddItemDialog.setCancelable(true);
btn_cancel_receipt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddItemDialog.dismiss();
}
});
btn_add_receipt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddData();
//add item to rv2
AddItemDialog.dismiss();
}
});
}
});
}
#Override
public int getItemCount() {
return contracts.size();
}
private void addAnItem(AddPayments payment) {
payments = ApplicationClass.paymentList;
payments.add(payment);
this.notifyDataSetChanged();
}
private void AddData() {
String c_code = contract_number_ADialog.getText().toString();
String c_mobile = mobile_number_ADialog.getText().toString();
String c_amount = et_amount_add.getText().toString();
AddPayments added_payment = new AddPayments(c_amount, c_code, c_mobile, "true");
payments.add(added_payment);
notifyDataSetChanged();
}
}
My Adapter class for the Second Recyclerview
public class AddPaymentsAdapter extends RecyclerView.Adapter<AddPaymentsAdapter.AddPayViewHolder> {
private ArrayList<AddPayments> payments;
Context mContext;
public AddPaymentsAdapter(Context context, ArrayList<AddPayments> addPayments) {
mContext = context ;
payments = addPayments;
}
public class AddPayViewHolder extends RecyclerView.ViewHolder{
TextView tv_contract_d, tv_amount_d, tv_isPending_d, tv_mobile_num_d;
ImageView btn_delete_item;
ConstraintLayout addedPaymentLayout;
public AddPayViewHolder(#NonNull View itemView) {
super(itemView);
addedPaymentLayout = itemView.findViewById(R.id.added_payment_item_id);
tv_contract_d = itemView.findViewById(R.id.tv_contract_d);
tv_amount_d = itemView.findViewById(R.id.tv_amount_d);
tv_isPending_d = itemView.findViewById(R.id.tv_isPending_d);
tv_mobile_num_d = itemView.findViewById(R.id.tv_mobile_num_d);
btn_delete_item = itemView.findViewById(R.id.btn_delete_item);
}
}
#NonNull
#Override
public AddPaymentsAdapter.AddPayViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.receipt_added_rv_item, viewGroup, false);
final AddPayViewHolder addPayViewHolder= new AddPayViewHolder(view);
return addPayViewHolder;
}
#Override
public void onBindViewHolder(#NonNull AddPaymentsAdapter.AddPayViewHolder addPayViewHolder, final int i) {
AddPayments currentItem = payments.get(i);
addPayViewHolder.itemView.setTag(payments.get(i));
addPayViewHolder.tv_contract_d.setText(payments.get(i).getAddContractCode());
addPayViewHolder.tv_isPending_d.setText(payments.get(i).getAddIsPending());
addPayViewHolder.tv_amount_d.setText(payments.get(i).getAddAmount());
addPayViewHolder.tv_mobile_num_d.setText(payments.get(i).getAddMobile());
addPayViewHolder.btn_delete_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//delete function
// Toast.makeText(mContext, "clicked delete icon inHoldernAdapter", Toast.LENGTH_SHORT).show();
removeItem(i);
}
});
}
#Override
public int getItemCount() {
return payments.size();
}
private void removeItem(int i) {
payments.remove(i);
this.notifyItemRemoved(i);
}
}
From your code in the adapter for the first recycler view you are using this method AddData(); to add data. But this method adds data to payments which is the list where you hold the data which you want to show in the second recycler view but have no connection to it(it's just a field of the adapter class).
The this.notifyDataSetChanged() notifies the current adapter for a change in data(first recycler view). You will need to add this data to the second recycler view adapter thou. You aren't doing that right now.
So a way would be to create a method inside of the fragment which takes a list of AddPayments as argument and add this data to the second recycler view adapater. It would be something like this:
Fragment method:
public void addSecondRVData(AddPayments itemToAdd) {
mAddPaymentsAdapter.addNewPayment(itemToAdd);
}
Second recycler view method:
public void addData(AddPayments itemToAdd) {
payments.add(itemToAdd);
this.notifyDataSetChanged():
}
Dont forget to initialize the payment list in the second recycler view.
Then in the first adapter do smth like this:
private ReceiptFragment receiptFragment;
//Constructor
public ContReceiptsAdapter(Context context, ArrayList<Contract> contractList, ReceiptFragment receiptFragment) {
contracts = contractList;
mContext = context;
this.receiptFragment = receiptFragment;
}
//Use this to add elements to second rv
receiptFragment.addSecondRVData(newItem);
Hope this helps although is not the cleanest solution. Check the example I wrote here because can't test it at the moment.

Categories

Resources