0

In my android Application, I added a recyclerview to show list of printing items. Each item view represents an information to print and also has a button to do printing. Print button color is light blue before printing and will change to yellow after printing . (printing code will execute here )

So, I clicked first print button and printed, button color was also changed to yellow . It is still okay to here. But, the problem is after scrolling to some distance, I found some buttons also changed color to yellow although it is not printed.

Here is my ViewHolder where I changed print button color in onClick() method.

public class IB17InventorySearchViewHolder extends BaseViewHolder<IB17InventorySearchResponse> {
    @BindView(R.id.tv_location)
    TextView tvLocation;
    @BindView(R.id.tv_tuNo)
    TextView tvTuNo;
    @BindView(R.id.tv_sku)
    TextView tvSku;
    @BindView(R.id.tv_lot_no)
    TextView tvLotNo;
    @BindView(R.id.tv_qty)
    TextView tvQty;
    @BindView(R.id.btn_print)
    Button btnPrint;
    IB17InventorySearchResponse inventorySearchResponse;
    private Activity mActivity;

    public IB17InventorySearchViewHolder(View itemView, Activity mActivity) {
        super(itemView);
        this.mActivity = mActivity;
    }

    @Override
    public void setData(IB17InventorySearchResponse data) {
        this.inventorySearchResponse = data;
        tvLocation.setText(data.getLoccode());
        tvTuNo.setText(data.getTuno1());
        tvSku.setText(data.getSkucode());
        tvLotNo.setText(data.getLot4());
        tvQty.setText(String.valueOf(data.getQty()));
        btnPrint.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_print) {
          if(BluetoothPrintHelper.printSucess)
            btnPrint.setBackgroundColor(Color.parseColor("#fff111"));

        } else {

            // for whole itemview click

        }
    }
}`

Here is my Adapter

public class IB17InventorySearchRecyAdapter extends BaseRecyclerAdapter<BaseViewHolder, BaseModel> {
private List<IB17InventorySearchResponse> searchResponseList;
public Context context;

public IB17InventorySearchRecyAdapter(Context context, List<IB17InventorySearchResponse> searchResponseList) {
    super(context);
    this.context = context;
    this.searchResponseList = searchResponseList;
}

@NonNull
@Override
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ib17_search_result_row, parent, false);
    return new IB17InventorySearchViewHolder(view, (Activity) context);
}

@Override
public void onBindViewHolder(BaseViewHolder holder, final int position) {
    holder.setData(searchResponseList.get(position));
}

@Override
public int getItemCount() {
    return searchResponseList.size();
}}

My Question is how should I change child view(button) color of viewholder in recyclerview without impacting other itemview childs(viewholder buttons) Any ideas or alternative ways are appreciating!

ZarNi Myo Sett Win
  • 1,353
  • 5
  • 15
  • 37
  • 1
    add boolean flag that stores the state of your button and set color of button based on its value. – karan Nov 28 '18 at 10:20
  • Later asking this question, I found a great article for handling viewstate in recycler view https://android.jlelse.eu/android-handling-checkbox-state-in-recycler-views-71b03f237022 – ZarNi Myo Sett Win Nov 30 '18 at 04:16

2 Answers2

2

This is because of how RecyclerView works. It recycles your view after it disappears from your screen. If you want to maintain the state of a view, you could keep track of it in a List. Example code for in your adapter:

private ArrayList<Integer> idsOfAllItemsThatHaveBeenPrinted = new ArrayList<>();

Then after the thing has been printed, you can add some identifier to the list

idsOfAllItemsThatHaveBeenPrinted.add(1);

now back in your onBindViewHolder you can check if your searchResponseList.get(position) is in that ArrayList. If it is in the ArrayList, change the background color to blue. If it IS NOT, then change it to yellow

IB17InventorySearchResponse x = searchResponseList.get(position)
if (idsOfAllItemsThatHaveBeenPrinted.contains(x.identifier)) {
// change to blue
else {
// change to yellow
}
Zun
  • 1,553
  • 3
  • 15
  • 26
  • Thanks @ZUNJAE, let me try. – ZarNi Myo Sett Win Nov 28 '18 at 10:28
  • You can have more idea about this subject : https://stackoverflow.com/questions/6711592/what-is-the-intent-of-the-methods-getitem-and-getitemid-in-the-android-class-bas – Sofiane Majdoub Nov 28 '18 at 10:46
  • it bad practice to solve this problem like this, you should use pojo class with a boolean , instead of making whole new list, which will increase time and space complexity by O(n). – Abhishek Garg Dec 21 '19 at 14:50
  • The way the RecyclerView works is it loads the model from the ArrayList and it recycles its views. This ArrayList is read only. Changing the value (your so called class with a boolean) on a model from this ArrayList doesn't mean the ArrayList gets updated. – Zun Jan 06 '20 at 12:02
2

What you can do is, add a boolean field to PoJo class of which the list is composed of. By default they all will be false. And when you'll press the print button set the value to true and notifies the adapter for the data change. Now set if that field is true then color will be Yellow else Green (or whatever you set).

Ashutosh Sagar
  • 981
  • 8
  • 20