在第一个位置打开 android 开关会自动在 recyclerview 中打开第 10 个开关

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

我正在开发一个应用程序,在该应用程序中,我在 recyclerview 中从服务器获取了一些数据。我的 recyclervew 列表布局包含 3 个视图 [ 文本视图(用于显示事件名称)、编辑图标(用于编辑名称)、一个用于打开 on/off 事件的开关。经过几天的工作,我在这个模块中发现了一个奇怪的问题,即当我打开第一个 pos 开关时,我会自动打开 recyclerview 中的第 10 个开关,如果名称少于 10 个,那么如果 9 那么所有开关都可以正常工作,然后在 10 号进入时,他们的行为如前所述,因此第 2 号转向第 11 号。就像 recylerview 排在第 10 位一样,依此类推。

我知道这很奇怪,但肯定是位置或其他问题。我用谷歌搜索但找不到任何东西。我正在 post 编写我的 adapter/list item.xml 的代码。如果您需要任何其他东西,我稍后会post。

::::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 ::::

 <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;
    }
}

这是由于View回收(来自class的名字)。当列表滚动时,视图被重用并绑定到新值。为使其正常工作,您的绑定函数必须在每次调用时设置检查状态。并且您的检查侦听器需要将检查状态写入模型 class 某处,因此如果您将该位置滚动到屏幕外然后再返回,则可以恢复它。

recycler view 的全部意义在于获得回收行为,这样您就可以最大限度地减少视图(非常重量级)的内存使用。它不仅仅是在列表中显示内容。看来你不明白 class 是如何工作的。

这里的问题是您正在检查是否从视图而不是模型检查了开关。该模型需要有一个布尔变量 isChecked,它决定视图是否被选中。您永远不应该检查是否从视图中检查了视图。 例如,

将此添加到您的 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());

并将您的模型更改为以下内容:

 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;
        }


}