Как использовать holder.todoCheckbox.setChecked? RecyclerView - PullRequest
0 голосов
/ 22 марта 2020

Как использовать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...