在第一个位置打开android开关会自动在recyclerview中打开第十个开关
我正在开发一个应用程序,其中我从recyclerview中的服务器获取了一些数据。我的RecyclerView列表布局包含3个视图[文本视图(显示事件名称),编辑图标(编辑名称),一个开关用于打开/关闭事件。经过几天的工作,我发现此模块中存在一个奇怪的问题,即当我打开第一个pos开关时,我会自动打开recyclerview中的第十个开关,如果少于10个名称(如果是9个),则所有开关都可以正常工作,然后在第十个输入时,它们会按照所述操作,因此会打开一个开关G2的位置是第11位,就像recylerview将第10位作为第一位,以此类推 我知道这很奇怪,但肯定是位置或其他方面有问题。我在谷歌上搜索了一下,但没有找到任何相关信息。我正在发布适配器/list item.xml的代码。如果您需要任何其他信息,我将稍后发布 ::eventAdapter.java::在第一个位置打开android开关会自动在recyclerview中打开第十个开关,android,android-recyclerview,android-switch,Android,Android Recyclerview,Android Switch,我正在开发一个应用程序,其中我从recyclerview中的服务器获取了一些数据。我的RecyclerView列表布局包含3个视图[文本视图(显示事件名称),编辑图标(编辑名称),一个开关用于打开/关闭事件。经过几天的工作,我发现此模块中存在一个奇怪的问题,即当我打开第一个pos开关时,我会自动打开recyclerview中的第十个开关,如果少于10个名称(如果是9个),则所有开关都可以正常工作,然后在第十个输入时,它们会按照所述操作,因此会打开一个开关G2的位置是第11位,就像recylerv
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);
}
}
}
<?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>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView_event"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
这是由于视图回收(从类的名称).视图被重用,并在列表滚动时绑定到新值。若要实现此功能,每次调用bind函数时必须设置检查状态。并且检查侦听器需要将检查状态写入某个模型类中,因此,如果您将该位置从屏幕上滚出,然后再返回,则可以将其还原
“回收者视图”的整个观点是获得回收行为,这样您就可以最大限度地减少视图(非常重)的内存使用。它不仅仅是在列表中显示内容。您似乎不了解类是如何工作的。这是由于视图回收(从类的名称开始).视图被重用,并在列表滚动时绑定到新值。若要实现此功能,每次调用bind函数时必须设置检查状态。并且检查侦听器需要将检查状态写入某个模型类中,因此,如果您将该位置从屏幕上滚出,然后再返回,则可以将其还原
recycler视图的整个观点是获得这种回收行为,这样您就可以最大限度地减少视图(非常重的视图)的内存使用。这不仅仅是在列表中显示内容。您似乎不了解类的工作原理。这里的问题是,您正在检查是否从视图而不是从模型中检查开关。模型需要检查布尔变量,以确定是否检查视图。您永远不应该检查视图是否从视图中检查。 比如说, 将此添加到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;
}
}
这里的问题是,您正在检查是否从视图而不是从模型中检查开关。模型需要检查一个布尔变量,以确定是否检查视图。您永远不应该检查是否从视图中检查视图。 比如说, 将此添加到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的行为,但我认为它会起作用,但它没有。你能给我介绍一下更多的事情,以及我如何使它起作用。基本上,你的onBindViewHolder需要设置用户或应用程序每次调用时都可以更改的所有内容。其他任何事情都会导致bug正如您在中看到的。这意味着需要在每次调用onBindViewHolder时设置选中状态。正如我所述,您的单击侦听器需要保存该状态,以便您可以在向后滚动时恢复该状态(或者,如果您滚动到屏幕外,则会丢失该状态).好的,你的意思是我应该在evey check change上保存状态,这样我就可以在页面重新加载时使用它们了?不仅仅是页面重新加载,还可以滚动。滚动时,如果每个屏幕有10个视图,那么索引0、10、20等也会使用相同的值。如果你想在向后滚动时使值正确,你必须将它们保存到某个模型上好的,我理解这比以往任何时候都重要,但我有一个问题,根据当前情况,如果toogle第一个开关通过一些方法调用将其保存到后端,它是否也会保存第十个开关?或者它的工作方式类似于保存时,我只会调用第一个开关的方法,如'model.get(position).setState(“true”)`???嘿,谢谢你的回复,是的,我有点了解recyclerview的行为,但我认为它会起作用,但它没有。你能给我介绍更多的事情,以及我如何使它起作用。基本上,你的onBindViewHolder需要设置用户或应用程序每次调用时都可以更改的所有内容。其他任何事情都会导致错误o类似于您在中看到的bug。这意味着需要在每次调用onBindViewHolder时设置选中状态。正如我所述,您的单击侦听器需要保存该状态,以便您可以在向后滚动时恢复该状态(或者,如果您滚动到屏幕外,则会丢失该状态).好的,你的意思是我应该在evey check change上保存状态,这样我就可以在页面重新加载时使用它们了?不仅仅是页面重新加载,还可以滚动。滚动时,如果每个屏幕有10个视图,那么索引0、10、20等也会使用相同的值。如果你想在向后滚动时使值正确,你必须将它们保存到某个模型上好的,我理解这比以往任何时候都重要,但我有一个问题,根据当前情况,如果toogle第一个开关通过一些方法调用将其保存到后端,它是否也会保存第十个开关?或者它的工作方式类似于保存时,我只会调用第一个开关的方法,如'model.get(position).setState(“true”)`请为我们输入
EventModel
类,我会帮助您更多好的,让我编辑问题@AlanDeep@AlanDeep请再勾选确定一件事,您何时切换开关?当您同时单击cardview时?否,在card view上,它只会告诉是否激活,仅在切换开关时切换请将告诉我们EventModel
课程,我会帮你更多好的,让我来编辑这个问题@AlanDeep@AlanD