RecyclerView 复选框在布局切换时失去价值
RecyclerView Checkboxes lose value when layout switched
我的 recyclerview 有问题。似乎每当 phone 变成横向模式,或者在应用程序中切换布局时,之前选择的复选框都不会恢复。
编辑---------------------------------------- ----
这是我的回收适配器:
public MyRecyclerAdapter(Context context, ArrayList<Workout> workout) {
mContext = context;
this.workout = workout;
}
// INITIALIZE HOLDER
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.workout_item, null);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.exercise.setText(workout.get(position).getExercise());
holder.percent.setText(workout.get(position).getPercent());
holder.reps.setText(workout.get(position).getReps());
holder.weight.setText(workout.get(position).getWeight());
holder.check1.setOnCheckedChangeListener(null);
final Workout isCheck = workout.get(position);
holder.check1.setChecked(isCheck.isCheck1());
holder.check1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
isCheck.setCheck1(isChecked);
}
});
}
这是在每个片段中设置适配器的地方class(这是在 onCreateView 中):
//RECYCLERVIEW
RecyclerView rv = (RecyclerView) view.findViewById(R.id.mRecyclerWed);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new MyRecyclerAdapter(this.getActivity(), getWedWorkout()));
return view;
}
这里是设置片段的地方:
public class WorkoutDaysActivity extends BaseActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.workout_days);
mToolBar = activateToolbar();
setUpNavigationDrawer();
getSupportActionBar().setTitle("Workout");
ViewPager vp = (ViewPager) findViewById(R.id.view_pager);
this.addPages(vp);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(vp);
tabLayout.setOnTabSelectedListener(listener(vp));
}
//ADD ALL PAGES
private void addPages(ViewPager pager) {
MyFragPagerAdapter adapter = new MyFragPagerAdapter(getSupportFragmentManager());
Intent intent = getIntent();
String workout = intent.getStringExtra("workout");
Bundle args = new Bundle();
args.putString("workout", workout);
MondayFragment mondayFragment = new MondayFragment();
mondayFragment.setArguments(args);
adapter.addPage(mondayFragment);
WedFragment wedFragment = new WedFragment();
wedFragment.setArguments(args);
adapter.addPage(wedFragment);
FridayFragment fridayFragment = new FridayFragment();
fridayFragment.setArguments(args);
adapter.addPage(fridayFragment);
pager.setAdapter(adapter);
}
没错,每次关闭并重新打开时都会重新创建片段,方向改变时也会发生同样的情况。回答你的问题,是的!有一些方法可以解决这个问题,我会使用 SharedPraferences 来保存复选框的状态并将其恢复到该状态。例如?
int firstSecondOrThird; //first page, second page or thrid page.
public MyRecyclerAdapter(Context context, ArrayList<Workout> workout, int thePosition) {
mContext = context;
this.workout = workout;
this.firstSecondOrThird = thePosition;
}
final SharedPreferences prefs;
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.exercise.setText(workout.get(position).getExercise());
//...
prefs = mContext.getSharedPreferences("ehehehe", Context.MODE_PRIVATE);
holder.check1.setChecked(prefs.getBoolean(firstSecondOrThird+"checkState"+position, false)); //restore the state of the CheckBox
isCheck.setCheck1(prefs.getBoolean(firstSecondOrThird+"checkState"+position, false)); //not sure what's this just copying from you ^^
holder.check1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
isCheck.setCheck1(isChecked);
prefs.edit().putBoolean(firstSecondOrThird+"checkState"+position, isChecked).apply(); //save the CheckBox's state
}
});
}
然后像这样启动它:
RecyclerView rv = (RecyclerView) view.findViewById(R.id.mRecyclerWed);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new MyRecyclerAdapter(this.getActivity(), getWedWorkout(), 1)); //in your first page
RecyclerView rv = (RecyclerView) view.findViewById(R.id.mRecyclerWed);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new MyRecyclerAdapter(this.getActivity(), getWedWorkout(), 2)); //in your second page, and 3 or the third
您是否尝试过保留片段实例?
在此处查看 Android 开发参考:
https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
控制片段实例是否在 Activity 重新创建(例如从配置更改)中保留。这只能用于不在返回堆栈中的片段。如果设置,片段生命周期将在重新创建 activity 时略有不同
我的 recyclerview 有问题。似乎每当 phone 变成横向模式,或者在应用程序中切换布局时,之前选择的复选框都不会恢复。
编辑---------------------------------------- ----
这是我的回收适配器:
public MyRecyclerAdapter(Context context, ArrayList<Workout> workout) {
mContext = context;
this.workout = workout;
}
// INITIALIZE HOLDER
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.workout_item, null);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.exercise.setText(workout.get(position).getExercise());
holder.percent.setText(workout.get(position).getPercent());
holder.reps.setText(workout.get(position).getReps());
holder.weight.setText(workout.get(position).getWeight());
holder.check1.setOnCheckedChangeListener(null);
final Workout isCheck = workout.get(position);
holder.check1.setChecked(isCheck.isCheck1());
holder.check1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
isCheck.setCheck1(isChecked);
}
});
}
这是在每个片段中设置适配器的地方class(这是在 onCreateView 中):
//RECYCLERVIEW
RecyclerView rv = (RecyclerView) view.findViewById(R.id.mRecyclerWed);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new MyRecyclerAdapter(this.getActivity(), getWedWorkout()));
return view;
}
这里是设置片段的地方:
public class WorkoutDaysActivity extends BaseActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.workout_days);
mToolBar = activateToolbar();
setUpNavigationDrawer();
getSupportActionBar().setTitle("Workout");
ViewPager vp = (ViewPager) findViewById(R.id.view_pager);
this.addPages(vp);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(vp);
tabLayout.setOnTabSelectedListener(listener(vp));
}
//ADD ALL PAGES
private void addPages(ViewPager pager) {
MyFragPagerAdapter adapter = new MyFragPagerAdapter(getSupportFragmentManager());
Intent intent = getIntent();
String workout = intent.getStringExtra("workout");
Bundle args = new Bundle();
args.putString("workout", workout);
MondayFragment mondayFragment = new MondayFragment();
mondayFragment.setArguments(args);
adapter.addPage(mondayFragment);
WedFragment wedFragment = new WedFragment();
wedFragment.setArguments(args);
adapter.addPage(wedFragment);
FridayFragment fridayFragment = new FridayFragment();
fridayFragment.setArguments(args);
adapter.addPage(fridayFragment);
pager.setAdapter(adapter);
}
没错,每次关闭并重新打开时都会重新创建片段,方向改变时也会发生同样的情况。回答你的问题,是的!有一些方法可以解决这个问题,我会使用 SharedPraferences 来保存复选框的状态并将其恢复到该状态。例如?
int firstSecondOrThird; //first page, second page or thrid page.
public MyRecyclerAdapter(Context context, ArrayList<Workout> workout, int thePosition) {
mContext = context;
this.workout = workout;
this.firstSecondOrThird = thePosition;
}
final SharedPreferences prefs;
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.exercise.setText(workout.get(position).getExercise());
//...
prefs = mContext.getSharedPreferences("ehehehe", Context.MODE_PRIVATE);
holder.check1.setChecked(prefs.getBoolean(firstSecondOrThird+"checkState"+position, false)); //restore the state of the CheckBox
isCheck.setCheck1(prefs.getBoolean(firstSecondOrThird+"checkState"+position, false)); //not sure what's this just copying from you ^^
holder.check1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
isCheck.setCheck1(isChecked);
prefs.edit().putBoolean(firstSecondOrThird+"checkState"+position, isChecked).apply(); //save the CheckBox's state
}
});
}
然后像这样启动它:
RecyclerView rv = (RecyclerView) view.findViewById(R.id.mRecyclerWed);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new MyRecyclerAdapter(this.getActivity(), getWedWorkout(), 1)); //in your first page
RecyclerView rv = (RecyclerView) view.findViewById(R.id.mRecyclerWed);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new MyRecyclerAdapter(this.getActivity(), getWedWorkout(), 2)); //in your second page, and 3 or the third
您是否尝试过保留片段实例?
在此处查看 Android 开发参考: https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
控制片段实例是否在 Activity 重新创建(例如从配置更改)中保留。这只能用于不在返回堆栈中的片段。如果设置,片段生命周期将在重新创建 activity 时略有不同