在第一个位置打开 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;
}
}
我正在开发一个应用程序,在该应用程序中,我在 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;
}
}