Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在设备旋转时恢复Android RecyclerView列表项中的复选框状态_Android_Android Recyclerview_Android Checkbox_Android Viewmodel - Fatal编程技术网

如何在设备旋转时恢复Android RecyclerView列表项中的复选框状态

如何在设备旋转时恢复Android RecyclerView列表项中的复选框状态,android,android-recyclerview,android-checkbox,android-viewmodel,Android,Android Recyclerview,Android Checkbox,Android Viewmodel,我当前的Android应用程序包含一个RecyclerView,列表中的每个项目都有一个复选框 我的问题是,在屏幕旋转时,复选框总是返回到未选中状态 我将更新后的列表项存储在我的activities ViewModel中,并将此保存的列表传递回onCreate中的适配器 从调试日志中,我可以看到列表状态正确地保存了每个列表项的选中/未选中状态 我还注销了适配器构造函数中的列表,该列表还显示选中状态仍然有效 但是,当调用onBindViewHolder时,列表项都未选中 以下是我的代码片段:-

我当前的Android应用程序包含一个RecyclerView,列表中的每个项目都有一个复选框

我的问题是,在屏幕旋转时,复选框总是返回到未选中状态

我将更新后的列表项存储在我的activities ViewModel中,并将此保存的列表传递回onCreate中的适配器

从调试日志中,我可以看到列表状态正确地保存了每个列表项的选中/未选中状态

我还注销了适配器构造函数中的列表,该列表还显示选中状态仍然有效

但是,当调用
onBindViewHolder
时,列表项都未选中

以下是我的代码片段:-

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

        manageViewModel();
        recyclerView = findViewById(R.id.my_rv);

        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        adapter = new MedicationAdapter(viewModel.getList(), this);
        recyclerView.setAdapter(adapter);

   }



protected void onSaveInstanceState(Bundle state) {
    super.onSaveInstanceState(state);
    viewModel.saveList(adapter.getList());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
}
<android.support.v7.widget.AppCompatCheckBox
            android:id="@+id/my_checkbox_header"
            android:layout_width="wrap_content"
            android:saveEnabled="false"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:text="" />
    public class MusicalAdapter extends RecyclerView.Adapter<MusicalAdapter.ViewHolder> {

        private static final String TAG = "MusicalAdapter";
        private int previousExpandedPosition = -1;
        private int mExpandedPosition = -1;

        private final List<MusicalUI> musicals = new ArrayList<>();
        private final ItemClickListener clickListener;

        MusicalAdapter(final List<MusicalUI> musicals, final ItemClickListener clickListener) {
            this.musicals.clear();
            this.musicals.addAll(musicals);
//AT THIS POINT THE CHECKED VALUES ARE AS EXPECTED

            this.clickListener = clickListener;
        }

        @NonNull
        @Override
        public MusicalAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.all_disco_item_x, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull final MusicalAdapter.ViewHolder holder, final int position) {
            final MusicalUI musical = musicals.get(position);

            Log.d(TAG, "onBindViewHolder() called with: musical = [" + musical.getChecked());

// AT THI SPOINT THE CHECKED VALUES ARE ALWAYS FALSE!!!!!!!!
            final boolean isExpanded = position == mExpandedPosition;


            for (final MusicalUI musicalx : musicals) {
                Log.d(TAG, "onBindViewHolder(): " + musicalx.getChecked());
            }

            // Header
            holder.discoDetailsHeaderLayout.setVisibility(View.VISIBLE);
            holder.musicalNameHeader.setText(musical.getDiscoName());

            holder.discoSelectedHeader.setOnCheckedChangeListener(null);
            holder.discoSelectedHeader.setChecked(musical.getChecked());
            holder.discoSelectedHeader.setOnCheckedChangeListener((buttonView, isChecked) -> musical.setChecked(isChecked));


            if (isExpanded)
                previousExpandedPosition = position;

            holder.itemView.setOnClickListener(v -> {
                mExpandedPosition = isExpanded ? -1 : position;
                notifyItemChanged(previousExpandedPosition);
                notifyItemChanged(position);
            });

        }

        @Override
        public int getItemCount() {
            return musicals.size();
        }


        MusicalUI getItem(final int position) {
            return musicals.get(position);
        }

        void updateList(final List<MusicalUI> newMusicals) {
            final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new GenericDiffUtilCallback<>(this.musicals, newMusicals));
            diffResult.dispatchUpdatesTo(this);

            this.musicals.clear();
            this.musicals.addAll(newMusicals);
        }

        List<MusicalUI> getList() {
            return musicals;
        }

        /**
         *
         */
        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
    ...
            }


        }
    }
我的列表项复选框在xml中定义如下:-

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

        manageViewModel();
        recyclerView = findViewById(R.id.my_rv);

        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        adapter = new MedicationAdapter(viewModel.getList(), this);
        recyclerView.setAdapter(adapter);

   }



protected void onSaveInstanceState(Bundle state) {
    super.onSaveInstanceState(state);
    viewModel.saveList(adapter.getList());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
}
<android.support.v7.widget.AppCompatCheckBox
            android:id="@+id/my_checkbox_header"
            android:layout_width="wrap_content"
            android:saveEnabled="false"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:text="" />
    public class MusicalAdapter extends RecyclerView.Adapter<MusicalAdapter.ViewHolder> {

        private static final String TAG = "MusicalAdapter";
        private int previousExpandedPosition = -1;
        private int mExpandedPosition = -1;

        private final List<MusicalUI> musicals = new ArrayList<>();
        private final ItemClickListener clickListener;

        MusicalAdapter(final List<MusicalUI> musicals, final ItemClickListener clickListener) {
            this.musicals.clear();
            this.musicals.addAll(musicals);
//AT THIS POINT THE CHECKED VALUES ARE AS EXPECTED

            this.clickListener = clickListener;
        }

        @NonNull
        @Override
        public MusicalAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.all_disco_item_x, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull final MusicalAdapter.ViewHolder holder, final int position) {
            final MusicalUI musical = musicals.get(position);

            Log.d(TAG, "onBindViewHolder() called with: musical = [" + musical.getChecked());

// AT THI SPOINT THE CHECKED VALUES ARE ALWAYS FALSE!!!!!!!!
            final boolean isExpanded = position == mExpandedPosition;


            for (final MusicalUI musicalx : musicals) {
                Log.d(TAG, "onBindViewHolder(): " + musicalx.getChecked());
            }

            // Header
            holder.discoDetailsHeaderLayout.setVisibility(View.VISIBLE);
            holder.musicalNameHeader.setText(musical.getDiscoName());

            holder.discoSelectedHeader.setOnCheckedChangeListener(null);
            holder.discoSelectedHeader.setChecked(musical.getChecked());
            holder.discoSelectedHeader.setOnCheckedChangeListener((buttonView, isChecked) -> musical.setChecked(isChecked));


            if (isExpanded)
                previousExpandedPosition = position;

            holder.itemView.setOnClickListener(v -> {
                mExpandedPosition = isExpanded ? -1 : position;
                notifyItemChanged(previousExpandedPosition);
                notifyItemChanged(position);
            });

        }

        @Override
        public int getItemCount() {
            return musicals.size();
        }


        MusicalUI getItem(final int position) {
            return musicals.get(position);
        }

        void updateList(final List<MusicalUI> newMusicals) {
            final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new GenericDiffUtilCallback<>(this.musicals, newMusicals));
            diffResult.dispatchUpdatesTo(this);

            this.musicals.clear();
            this.musicals.addAll(newMusicals);
        }

        List<MusicalUI> getList() {
            return musicals;
        }

        /**
         *
         */
        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
    ...
            }


        }
    }

在设备旋转时,将复选框状态保留在RecyclerView项中的正确方法是什么

我的适配器代码:-

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

        manageViewModel();
        recyclerView = findViewById(R.id.my_rv);

        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        adapter = new MedicationAdapter(viewModel.getList(), this);
        recyclerView.setAdapter(adapter);

   }



protected void onSaveInstanceState(Bundle state) {
    super.onSaveInstanceState(state);
    viewModel.saveList(adapter.getList());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
}
<android.support.v7.widget.AppCompatCheckBox
            android:id="@+id/my_checkbox_header"
            android:layout_width="wrap_content"
            android:saveEnabled="false"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:text="" />
    public class MusicalAdapter extends RecyclerView.Adapter<MusicalAdapter.ViewHolder> {

        private static final String TAG = "MusicalAdapter";
        private int previousExpandedPosition = -1;
        private int mExpandedPosition = -1;

        private final List<MusicalUI> musicals = new ArrayList<>();
        private final ItemClickListener clickListener;

        MusicalAdapter(final List<MusicalUI> musicals, final ItemClickListener clickListener) {
            this.musicals.clear();
            this.musicals.addAll(musicals);
//AT THIS POINT THE CHECKED VALUES ARE AS EXPECTED

            this.clickListener = clickListener;
        }

        @NonNull
        @Override
        public MusicalAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.all_disco_item_x, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull final MusicalAdapter.ViewHolder holder, final int position) {
            final MusicalUI musical = musicals.get(position);

            Log.d(TAG, "onBindViewHolder() called with: musical = [" + musical.getChecked());

// AT THI SPOINT THE CHECKED VALUES ARE ALWAYS FALSE!!!!!!!!
            final boolean isExpanded = position == mExpandedPosition;


            for (final MusicalUI musicalx : musicals) {
                Log.d(TAG, "onBindViewHolder(): " + musicalx.getChecked());
            }

            // Header
            holder.discoDetailsHeaderLayout.setVisibility(View.VISIBLE);
            holder.musicalNameHeader.setText(musical.getDiscoName());

            holder.discoSelectedHeader.setOnCheckedChangeListener(null);
            holder.discoSelectedHeader.setChecked(musical.getChecked());
            holder.discoSelectedHeader.setOnCheckedChangeListener((buttonView, isChecked) -> musical.setChecked(isChecked));


            if (isExpanded)
                previousExpandedPosition = position;

            holder.itemView.setOnClickListener(v -> {
                mExpandedPosition = isExpanded ? -1 : position;
                notifyItemChanged(previousExpandedPosition);
                notifyItemChanged(position);
            });

        }

        @Override
        public int getItemCount() {
            return musicals.size();
        }


        MusicalUI getItem(final int position) {
            return musicals.get(position);
        }

        void updateList(final List<MusicalUI> newMusicals) {
            final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new GenericDiffUtilCallback<>(this.musicals, newMusicals));
            diffResult.dispatchUpdatesTo(this);

            this.musicals.clear();
            this.musicals.addAll(newMusicals);
        }

        List<MusicalUI> getList() {
            return musicals;
        }

        /**
         *
         */
        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
    ...
            }


        }
    }
公共类MusicalAdapter扩展了RecyclerView.Adapter{
私有静态最终字符串标记=“MusicalAdapter”;
private int previousExpandedPosition=-1;
私有int-mExpandedPosition=-1;
私人最终列表音乐剧=新ArrayList();
私有最终项clickListener clickListener;
MusicalAdapter(最终列表音乐剧、最终项目clickListener clickListener){
这个。音乐剧。清晰();
这个。音乐剧。阿达尔(音乐剧);
//此时,检查值与预期值相同
this.clickListener=clickListener;
}
@非空
@凌驾
public MusicalAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup父级,final int viewType){
最终视图=LayoutInflater.from(parent.getContext()).flate(R.layout.all\u disco\u item\u x,parent,false);
返回新的ViewHolder(视图);
}
@凌驾
public void onBindViewHolder(@NonNull final MusicalAdapter.ViewHolder,final int position){
最终音乐剧ui music=音乐剧。获取(位置);
d(标记“onBindViewHolder()”,调用时使用:music=[“+music.getChecked());
//在该点,检查值始终为假!!!!!!!!
最终布尔值isExpanded=position==MeExpandedPosition;
为(最终音乐剧UI音乐剧:音乐剧){
Log.d(标记“onBindViewHolder():”+musicalx.getChecked());
}
//标题
holder.discoDetailsHeaderLayout.setVisibility(View.VISIBLE);
holder.musicalNameHeader.setText(musical.getdiscome());
holder.discoSelectedHeader.setOnCheckedChangeListener(空);
holder.discoSelectedHeader.setChecked(music.getChecked());
holder.discoSelectedHeader.setOnCheckedChangeListener((按钮视图,已检查)->music.setChecked(已检查));
如果(扩展)
先前扩展的位置=位置;
holder.itemView.setOnClickListener(v->{
mExpandedPosition=isExpanded?-1:位置;
notifyItemChanged(先前的ExpandedPosition);
(职位)变更;
});
}
@凌驾
public int getItemCount(){
返回音乐剧。大小();
}
MusicalUI getItem(最终整数位置){
返回音乐剧。获取(位置);
}
void updateList(新音乐剧最终列表){
final DiffUtil.diffiesult diffiesult=DiffUtil.calculateDiff(新通用diffutilcallback(this.musicals,newMusicals));
diffResult.dispatchUpdatesTo(本);
这个。音乐剧。清晰();
这部.音乐剧.addAll(新音乐剧);
}
List getList(){
回归音乐剧;
}
/**
*
*/
公共类ViewHolder扩展了RecyclerView.ViewHolder实现了View.OnClickListener、CompoundButton.OnCheckedChangeListener{
...
}
}
}

它之所以改变,是因为当轮换发生变化时,您的活动会重新启动。您可以编写大量代码来恢复您的状态,也可以避免重新启动。这是正确的方法

使您的活动不会在轮换更改中重新启动

在AndroidManifest中找到您的活动并添加

android:configChanges=“orientation”

Android还建议在大多数情况下避免使用它

它说让android自己处理配置更改

注意:自行处理配置更改可能会使更改更加复杂 更难使用替代资源,因为系统确实如此 不会自动为您应用它们。此技术应 当您必须避免由于故障而重新启动时,被认为是最后的选择 大多数应用程序都不建议更改配置和配置

要声明您的活动处理配置更改,请编辑 在清单文件中包含 android:configChanges属性的值表示 要处理的配置。中列出了可能的值 android:configChanges属性的文档 常用值为“方向”、“屏幕大小”和 “键盘隐藏”。“方向”值防止在 屏幕方向改变


检查我的答案,它会给你一个答案hint@NileshRathod,我的PoJo已经有一个布尔字段,该字段设置正确,直到我尝试在onBindViewHolder中使用它,然后它始终为false。即使我使用有效的“选中”列表创建了我的recyclerView适配器。请与我共享适配器代码