0

I am changing icon of button when I click on it inside recyclerview item, but other button's icons getting changed. Not all of icons effecting but some getting effected. I have no idea how to detect this.

public class MainActivity extends AppCompatActivity {

    private RecyclerView Items;
    private ItemListAdapter ItemAdapter;
    private ArrayList<ItemDataModel> ItemList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try{setContentView(R.layout.activity_main);

        ItemList = new ArrayList<ItemDataModel>();
        ItemList.add(new ItemDataModel("Data1", 1.00));
        ItemList.add(new ItemDataModel("Data2", 2.00));
        ItemList.add(new ItemDataModel("Data3", 3.00));
        ItemList.add(new ItemDataModel("Data4", 4.00));
        ItemList.add(new ItemDataModel("Data5", 5.00));
        ItemList.add(new ItemDataModel("Data6", 6.00));
        ItemList.add(new ItemDataModel("Data7", 7.00));
        ItemList.add(new ItemDataModel("Data8", 8.00));
        ItemList.add(new ItemDataModel("Data9", 9.00));
        ItemList.add(new ItemDataModel("Data10", 10.00));
        ItemList.add(new ItemDataModel("Data11", 11.00));
        ItemList.add(new ItemDataModel("Data12", 12.00));
        ItemList.add(new ItemDataModel("Data13", 13.00));
        ItemList.add(new ItemDataModel("Data14", 14.00));
        ItemList.add(new ItemDataModel("Data15", 15.00));
        ItemList.add(new ItemDataModel("Data16", 16.00));
        ItemList.add(new ItemDataModel("Data17", 17.00));
        ItemList.add(new ItemDataModel("Data18", 18.00));
        ItemList.add(new ItemDataModel("Data19", 19.00));
        ItemList.add(new ItemDataModel("Data20", 20.00));

        ItemAdapter = new ItemListAdapter(ItemList);

        Items = (RecyclerView) findViewById(R.id.Main_List);
        Items.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        Items.setAdapter(ItemAdapter);}
        catch (Exception e)
        {
         e.printStackTrace();
        }}
class ItemDataModel{
    public String Desc;
    public double sPrice;
    public ItemDataModel(String De, double sp){
        Desc = De;
        sPrice = sp;
    }
}
class ItemHolder extends RecyclerView.ViewHolder {
    public TextView Desc, Update;
    public EditText Prices;

    public ItemHolder(View view) {
        super(view);
        Desc = (TextView) view.findViewById(R.id.ListRow_Desc);
        Prices = (EditText) view.findViewById(R.id.ListRow_Price);
        Update = (TextView) view.findViewById(R.id.ListRow_Update);
    }
}
class ItemListAdapter extends RecyclerView.Adapter<ItemHolder> {
    private ArrayList<ItemDataModel> arrayList;

    public ItemListAdapter(ArrayList<ItemDataModel> arrayList) {
        this.arrayList = arrayList;
    }

    @Override
    public int getItemCount() {
        return (arrayList != null ? arrayList.size() : 0);
    }

    @Override
    public void onBindViewHolder(ItemHolder holder, final int position) {
        final ItemDataModel model = arrayList.get(position);
        final ItemHolder mainHolder = (ItemHolder) holder;

        mainHolder.Desc.setText(model.Desc);
        mainHolder.Prices.setText(String.format("%1$.2f", model.sPrice));
        mainHolder.Update.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (mainHolder.Prices.isEnabled()) {
                            mainHolder.Prices.setEnabled(false);
                            mainHolder.Prices.clearFocus();
                            model.sPrice = Double.valueOf(mainHolder.Prices.getText().toString());
                            mainHolder.Prices.setText(String.format("%1$.2f", model.sPrice));
                            mainHolder.Update.setCompoundDrawablesWithIntrinsicBounds(R.drawable.profile, 0, 0, 0);
                        } else
                        {
                            mainHolder.Prices.setEnabled(true);
                            mainHolder.Prices.requestFocus();
                            mainHolder.Update.setCompoundDrawablesWithIntrinsicBounds(R.drawable.checked,0,0,0);
                        }
                    }
                }
        );
    }

    @Override
    public ItemHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        LayoutInflater mInflater = LayoutInflater.from(viewGroup.getContext());

        ViewGroup mainGroup = (ViewGroup) mInflater.inflate(R.layout.list_row, viewGroup, false);
        ItemHolder mainHolder = new ItemHolder(mainGroup);
        return mainHolder;
    }
}
class ProdCatSubDataModel implements Parcelable {
    public String Name;
    public int ID;

    public ProdCatSubDataModel(Parcel source){
        Name = source.readString();
        ID = source.readInt();
    }

    public ProdCatSubDataModel(){}

    public int describeContents(){
        return this.hashCode();
    }

    public void writeToParcel(Parcel dest, int flags){
        dest.writeString(Name);
        dest.writeInt(ID);
    }

    public final Parcelable.Creator CREATOR = new Parcelable.Creator(){
        public ProdCatSubDataModel createFromParcel(Parcel in){
            return new ProdCatSubDataModel(in);
        }
        public ProdCatSubDataModel[] newArray(int size){return new ProdCatSubDataModel[size];}
    };
}

}

Activity

<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"  android:layout_marginLeft = "5dp"
    android:layout_marginRight="5dp">
    <android.support.v7.widget.RecyclerView android:id="@+id/Main_List"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:visibility="visible"/>

</RelativeLayout>

Item Row

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="@+id/List_RowLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    app:cardPreventCornerOverlap="false" app:cardElevation="3dp"
    app:cardUseCompatPadding="true" >

    <RelativeLayout android:layout_width ="fill_parent" android:layout_height="wrap_content"
         android:padding="5dp" >



        <TextView android:id="@+id/ListRow_Desc"
            android:layout_width="fill_parent" android:layout_height="52dp"
            android:textSize="12dp"
            android:text="Sample" />

        <EditText android:id="@+id/ListRow_Price" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:gravity="bottom"
            android:textSize= "15dp" android:enabled="false"
             android:text="9999"
            android:layout_toLeftOf="@+id/ListRow_Update" android:layout_below="@+id/ListRow_Desc"
            android:layout_marginRight="10dp" android:inputType="numberDecimal"/>

        <TextView android:id="@+id/ListRow_Update"
            android:layout_alignParentRight="true" android:layout_below="@+id/ListRow_Desc"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:drawableLeft="@drawable/profile"
            android:layout_marginRight="10dp"/>
    </RelativeLayout>

</android.support.v7.widget.CardView> 
  • It should be because of View recycling. Please post your adapter class so we can help you better – Much Overflow Feb 24 '16 at 17:23
  • Please provide Your code so we can fix it. – Tony Babarino Feb 24 '16 at 17:25
  • That's because the RV reuses the objects that are gone off the screen. You may be observing every time you scroll your new icon appears on different vows. Take help from this http://stackoverflow.com/a/33848252/3209739 – cgr Feb 24 '16 at 17:30
  • Please see the attached code and suggest me some answer. every time i click on the edit button of one row to change its icon, other rows also getting effected. not all but some random row are getting effected. – Gagan Kalyana Feb 24 '16 at 17:57
  • Please help me with this issue.. – Gagan Kalyana Feb 29 '16 at 16:42

1 Answers1

0

This is because of view recycling. You can add a field inside of ItemDataModel to save the state of the button and restore the state of the button inside of onBindViewHolder. Something like this:

  class ItemDataModel{
    public String Desc;
    public double sPrice;
    public boolean clicked = false;
    public ItemDataModel(String De, double sp){
        Desc = De;
        sPrice = sp;
     }
    }



@Override
   public void onBindViewHolder(ItemHolder holder, final int position) {
   final ItemDataModel model = arrayList.get(position);
   if(model.clicked){
      //Set the state of the button when is clicked
   }else{
      //Set initial state
   }
   new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        model.clicked = true;

                });
    }
cherif
  • 1,164
  • 1
  • 11
  • 16
  • I have already tried this. but no outcome. Please suggest something else. it would be really appriciated. – Gagan Kalyana Feb 25 '16 at 04:23
  • https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView https://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/ – Gagan Kalyana Mar 01 '16 at 12:18