Как использовать holder.todoCheckbox.setChecked (todoBool);
У меня есть вид рециркулятора, который содержит 3 держателя вида. У меня есть MainActivity, HeaderFooterAdapter, SimpleItamAdapter.
У меня есть логика c, когда я нажимаю на флажок, который будет фильтровать список. В setOnCheckedChangeListener я установил для переменных todoBool, doneBool, projectBool новые значения истинности. Затем я хотел бы установить флажки в true или false в зависимости от этих значений.
Проблема возникает в этой строке кода
holder.todoCheckbox.setChecked(todoBool);
Это вызывает cra * sh в приложении .
public void onBindHeaderItemViewHolder(@NonNull HeaderViewHolder holder, int localPosition) {
applyFullSpanForStaggeredGridLayoutManager(holder);
//This following 3 lines causes error. how to manage this?
holder.todoCheckbox.setChecked(todoBool);
holder.doneCheckbox.setChecked(doneBool);
holder.projektCheckbox.setChecked(projectBool);
holder.todoCheckbox.setOnCheckedChangeListener(…); //here i set to Bools
holder.doneCheckbox.setOnCheckedChangeListener(…);
holder.projektCheckbox.setOnCheckedChangeListener(…);
}
Я попробовал это. Также вызывает в приложении cra sh.
holder.todoCheckbox.setChecked(false);
holder.doneCheckbox.setChecked(false);
holder.projektCheckbox.setChecked(false);
Что я делаю не так? Я толкнул все здесь. «Местная ветка» не работает. "DevMaster" работает. https://github.com/SaschaGolod/T09b.10-Exercise-AddViewModelToAddTaskActivity
Большое спасибо, если кто-то может помочь мне здесь
Вот весь мой класс адаптера:
package com.example.android.todolist.adapters;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import com.example.android.todolist.R;
import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils;
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import static com.example.android.todolist.MainActivity.onItemClickedDefault;
import static com.example.android.todolist.MainActivity.onItemClickedDone;
import static com.example.android.todolist.MainActivity.onItemClickedProject;
import static com.example.android.todolist.MainActivity.onItemClickedTodo;
public class DemoHeaderFooterAdapter
extends AbstractHeaderFooterWrapperAdapter<DemoHeaderFooterAdapter.HeaderViewHolder, DemoHeaderFooterAdapter.FooterViewHolder>
implements View.OnClickListener {
private static final String TAG = "DemoHeaderFooterAdapter";
private OnListItemClickMessageListener mOnItemClickListener;
private Context mContext;
private boolean todoBool = false;
private boolean doneBool = false;
private boolean projectBool = false;
static class HeaderViewHolder extends RecyclerView.ViewHolder {
private CheckBox todoCheckbox;
private CheckBox doneCheckbox;
private CheckBox projektCheckbox;
HeaderViewHolder(View itemView) {
super(itemView);
todoCheckbox = itemView.findViewById(R.id.todoCheckboxID);
doneCheckbox = itemView.findViewById(R.id.doneCheckboxID);
projektCheckbox = itemView.findViewById(R.id.projektCheckboxID);
Log.i(TAG, "onCreate finished");
}
}
static class FooterViewHolder extends RecyclerView.ViewHolder {
FooterViewHolder(View itemView) {
super(itemView);
}
}
public DemoHeaderFooterAdapter(RecyclerView.Adapter adapter, OnListItemClickMessageListener clickListener, Context mContext) {
Log.i(TAG, "DemoHeaderFooterAdapter");
setAdapter(adapter);
mOnItemClickListener = clickListener;
this.mContext = mContext;
}
@Override
public int getHeaderItemCount() {
return 1;
}
@Override
public int getFooterItemCount() {
return 1;
}
@NonNull
@Override
public HeaderViewHolder onCreateHeaderItemViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.i(TAG, "HeaderViewHolder");
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_item, parent, false);
HeaderViewHolder vh = new HeaderViewHolder(v);
if (mOnItemClickListener != null) {
vh.itemView.setOnClickListener(this);
}
return vh;
}
@NonNull
@Override
public FooterViewHolder onCreateFooterItemViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_item, parent, false);
FooterViewHolder vh = new FooterViewHolder(v);
if (mOnItemClickListener != null) {
vh.itemView.setOnClickListener(this);
}
return vh;
}
@Override
public void onClick(@NonNull View v) {
RecyclerView rv = RecyclerViewAdapterUtils.getParentRecyclerView(v);
RecyclerView.ViewHolder vh = rv.findContainingViewHolder(v);
int rootPosition = vh.getAdapterPosition();
if (rootPosition == RecyclerView.NO_POSITION) {
return;
}
// need to determine adapter local position like this:
RecyclerView.Adapter rootAdapter = rv.getAdapter();
int localPosition = WrapperAdapterUtils.unwrapPosition(rootAdapter, this, rootPosition);
// get segment
long segmentedPosition = getSegmentedPosition(localPosition);
int segment = extractSegmentPart(segmentedPosition);
int offset = extractSegmentOffsetPart(segmentedPosition);
String message;
if (segment == SEGMENT_TYPE_HEADER) {
message = "CLICKED: Header item " + offset;
} else if (segment == SEGMENT_TYPE_FOOTER) {
message = "CLICKED: Footer item " + offset;
} else {
throw new IllegalStateException("Something wrong.");
}
mOnItemClickListener.onItemClicked(message);
}
// --------------------------------------------
// [ OPTIONAL ]
// Set full-span for Grid layout and Staggered Grid layout
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
setupFullSpanForGridLayoutManager(recyclerView);
}
@Override
public void onBindHeaderItemViewHolder(@NonNull HeaderViewHolder holder, int localPosition) {
applyFullSpanForStaggeredGridLayoutManager(holder);
//Maybe here is the mistake?
//Reload State of SharedPreferences
//This following 3 lines causes error :| how to manage this?
holder.todoCheckbox.setChecked(false);
holder.doneCheckbox.setChecked(false);
holder.projektCheckbox.setChecked(false);
holder.todoCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
todoBool = false;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedDefault);
}else{
todoBool = true;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedTodo);
}
}
});
holder.doneCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
todoBool = false;
doneBool = true;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedDone);
}else{
todoBool = false;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedDefault);
}
}
});
holder.projektCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
todoBool = true;
doneBool = false;
projectBool = true;
mOnItemClickListener.onItemClicked(onItemClickedProject);
}else{
todoBool = true;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedTodo);
}
}
});
}
@Override
public void onBindFooterItemViewHolder(@NonNull FooterViewHolder holder, int localPosition) {
applyFullSpanForStaggeredGridLayoutManager(holder);
}
// Filling span for GridLayoutManager
private void setupFullSpanForGridLayoutManager(RecyclerView recyclerView) {
RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
if (!(lm instanceof GridLayoutManager)) {
return;
}
final GridLayoutManager glm = (GridLayoutManager) lm;
final GridLayoutManager.SpanSizeLookup origSizeLookup = glm.getSpanSizeLookup();
final int spanCount = glm.getSpanCount();
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
final long segmentedPosition = getSegmentedPosition(position);
final int segment = extractSegmentPart(segmentedPosition);
final int offset = extractSegmentOffsetPart(segmentedPosition);
if (segment == SEGMENT_TYPE_NORMAL) {
return origSizeLookup.getSpanSize(offset);
} else {
return spanCount; // header or footer
}
}
});
}
private void applyFullSpanForStaggeredGridLayoutManager(RecyclerView.ViewHolder holder) {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
// Filling span for StaggeredGridLayoutManager
if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
((StaggeredGridLayoutManager.LayoutParams) lp).setFullSpan(true);
}
}
// --------------------------------------------
}
----- ------ Редактировать 3 ----------------
public void notifyTaskEntrysChanged(String message){
switch (message) {
//Here set Booleans
}
filteredTaskEntries.clear();
//Now fill the filteredTaskEntries with new TaskEntries depending on the bools
Log.d(TAG, "notifyDataSetChanged next Step");
notifyDataSetChanged(); //Error 1. Line in Logcat
}
------------ Edit2 ---- -------------
В MainActifity я обрабатываю щелчки следующим образом:
@Override
public void onItemClicked(String message) {
switch (message) {
case onItemClickedTodo:
Log.d(TAG, "onItemClickedTriggerd: TodoChecked true");
TodoChecked = true;
DoneChecked = false;
ProjectChecked = false;
break;
case onItemClickedDone:
TodoChecked = false;
DoneChecked = true;
ProjectChecked = false;
break;
case onItemClickedProject:
ProjectChecked = true;
TodoChecked = true;
DoneChecked = false;
break;
default:
ProjectChecked = false;
TodoChecked = false;
DoneChecked = false;
break;
}
saveStateOfButtons();
Log.d(TAG, "mFilteringAdapter.notifyTaskEntrysChanged(message)");
mFilteringAdapter.notifyTaskEntrysChanged(message); //Error 2. Line in Logcat
}
3. Строка Ошибка это код:
mOnItemClickListener.onItemClicked(onItemClickedDefault);
------------ Edit1 -----------------
Вот журнал. [...]
D/DemoHeaderFooterAdapter: ----------------------------------------------------
03-22 19:50:49.267 13331-13331/com.example.android.todoDB D/DemoHeaderFooterAdapter: TodoSetOnCheckedChangeListener triggerd
03-22 19:50:49.267 13331-13331/com.example.android.todoDB D/MainActivity: onItemClickedTriggerd: TodoChecked true
03-22 19:50:49.267 13331-13331/com.example.android.todoDB D/MainActivity: saveStateButtons
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/MainActivity: mFilteringAdapter.notifyTaskEntrysChanged(message)
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/SimpleDemoItemAdapter: notifyTaskEntrysChanged finished
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/SimpleDemoItemAdapter: notifyDataSetChanged next Step
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/AndroidRuntime: Shutting down VM
03-22 19:50:49.277 13331-13331/com.example.android.todoDB E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.todoDB, PID: 13331
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{e9fff59 VFED..... .F....ID 0,0-480,680 #7f090090 app:id/recycler_view}, adapter:com.example.android.todolist.adapters.DemoHeaderFooterAdapter@1c3071e, layout:androidx.recyclerview.widget.LinearLayoutManager@b695bff, context:com.example.android.todolist.MainActivity@755b94c
at androidx.recyclerview.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2880)
at [...]
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11997)
at androidx.recyclerview.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7070)
at com.example.android.todolist.adapters.SimpleDemoItemAdapter.notifyTaskEntrysChanged(SimpleDemoItemAdapter.java:287)