Search code examples
androidandroid-recyclerviewandroid-switch

Switching on android switch at 1st pos automatically switches the 10th switch on in recyclerview


I am working on an app in which I fetched some data from a server in recyclerview. My recyclervew list layout contains 3 view [ textview(to display event name), edit icon (to edit names), one Switch to turn on/off the events. After some days of working i found a weird issue in this module i.e. when i turns on the 1st pos switch i automatically switches on the 10th switch in the recyclerview, if there are less than 10 names say if 9 then all switches works fine, then on the entry of the 10th they act as mentioned and so one turning 2nd on turns the 11th on. It's like recylerview is taking 10th position as 1st and so on.

I know it's weird but there must be problem with position or something. I googled but could not find anything on this. I am posting the code of my adapter/list item.xml. if you need any other thing i will post it later.

::::eventAdapter.java::::

public class eventAdapter extends RecyclerView.Adapter<eventAdapter.UsersViewHolder> {

    Context context;
    List<EventModel> userListResponseData;

    public eventAdapter(Context context, List<EventModel> userListResponseData) {
        this.userListResponseData = userListResponseData;
        this.context = context;

    }

    @Override
    public UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(context).inflate(R.layout.event_list_items, parent,false);
        UsersViewHolder usersViewHolder = new UsersViewHolder(view);
        return usersViewHolder;
    }

    @Override
    public void onBindViewHolder(final UsersViewHolder holder, final int position) {
        // set the data
        final String eventName = userListResponseData.get(position).getEvent_name();
         holder.ed_eventname.setText(eventName);



        holder.ic_event_edit.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              FragmentActivity activity = (FragmentActivity)(context);
              FragmentManager fm = activity.getSupportFragmentManager();
              EditEvent_Dialog alertDialog = new EditEvent_Dialog();
              Bundle bundle = new Bundle();
              bundle.putString("event_name", eventName);
              alertDialog.setArguments(bundle);

              alertDialog.show(fm, "fragment_alert");
//
          }
      });

    holder.event_cardView.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                          boolean state=holder.EventSwitch.isChecked();
                          if (state){

                              Toast.makeText(context, eventName+" is Activated", Toast.LENGTH_SHORT).show();
                          }
                          else
                              Toast.makeText(context, eventName+" is Deactivated", Toast.LENGTH_SHORT).show();
                          }
                  });
          }

    @Override
    public int getItemCount() {
        return userListResponseData.size(); // size of the list items
    }

    class UsersViewHolder extends RecyclerView.ViewHolder {
        // init the item view's
        private TextView ed_eventname;
        private ImageView ic_event_edit;
        private Switch EventSwitch;
        private CardView event_cardView;

        public UsersViewHolder(View itemView) {
            super(itemView);
            // get the reference of item view's
            ed_eventname = (TextView) itemView.findViewById(R.id.fetchevent_name);
            ic_event_edit = (ImageView) itemView.findViewById(R.id.edit_event);
            EventSwitch = (Switch) itemView.findViewById(R.id.event_switch);
            event_cardView = (CardView) itemView.findViewById(R.id.event_list_card);
        }
    }
}

::::event_list_items.xml::::

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/event_list_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    card_view:cardBackgroundColor="@color/colorPrimary"
    card_view:cardCornerRadius="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="@color/colorPrimary">

        <TextView
        android:id="@+id/fetchevent_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:layout_gravity="left|center"
        android:padding="5dp"
        android:textSize="15sp"
        android:layout_margin="5dp"
        />
        <ImageView
            android:id="@+id/edit_event"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/pencilicon"
            android:layout_margin="5dp"
            android:layout_gravity="center"

            android:padding="5dp"/>
        <Switch
            android:id="@+id/event_switch"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_gravity="end|center"
            android:theme="@style/SwitchCompatTheme" />
    </LinearLayout>
</android.support.v7.widget.CardView>

:::: Recyclerview in main layout ::::

 <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView_event"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

::::EDIT::::

EventModel.java

public class EventModel {

    public String event_name;

    public EventModel(String event_name){
        this.event_name = event_name;
    }

    public EventModel(){

    }

    public void setEvent_name(String event_name) {
        this.event_name = event_name;
    }

    public String getEvent_name() {
        return event_name;
    }
}

Solution

  • The problem here is that you are checking if a switch is checked from the view and not from the model. The model needs to have a boolean variable isChecked, that determines whether the view is checked or not. You should never check if a view is checked from the view. For example,

    Add this to your onBindViewHolder:

     holder.EventSwitch.setOnClickListener(new View.OnClickListener() {
                          @Override
                          public void onClick(View v) {
                              boolean state=userListResponseData.get(position).isChecked();
                              userListResponseData.get(position).setChecked(!state);
    
                      });
              }
    
    
          holder.EventSwitch.setChecked(userListResponseData.get(position).isChecked());
    

    And change your model to the following:

     public class EventModel {
    
            public String event_name;
    
            private boolean checked;
    
            public boolean isChecked(){
                return checked;
            }
            public void setChecked(boolean checked){
                this.checked = checked;
    
            }
            public EventModel(String event_name){
                this.event_name = event_name;
            }
    
            public EventModel(){
    
            }
    
            public void setEvent_name(String event_name) {
                this.event_name = event_name;
            }
    
            public String getEvent_name() {
                return event_name;
            }
    
    
    }