显示时不检查在OnBindViewHolder中签入的CheckBox

时间:2016-05-30 05:52:28

标签: android android-recyclerview recycler-adapter

在我的回收商项目布局中,我有一个CheckBox,我在onBindView设置了检查状态。问题是,首次显示RecyclerView时,即使前三项应选中CheckBoxes,它们也会显示为未选中状态。但是在向下滚动列表并向上滚动后,它们会根据需要进行检查。我在OnBindViewHolder中设置了一个断点,每次都正确设置了检查状态。但出于某种原因,当它第一次被渲染时,它没有被检查。

我的RecyclerView适配器:

public class VideoAdapter extends ScrollBaseAdapter<VideoAdapter.VideoViewHolder>

    public class VideoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        CheckBox mBookmarkChkBox;

        public VideoViewHolder(View view) {

            mBookmarkChkBox = (CheckBox) view.findViewById(R.id.checkbox_bookmark_video);
                mBookmarkChkBox.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        bookmark(getAdapterPosition(), ((CheckBox)v).isChecked());
                    }
                });
        }

    @Override
    public VideoViewHolder myCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item_video, parent, false);
        return new VideoViewHolder(view);
    }

    @Override
    public void myBindViewHolder(final VideoViewHolder holder, final int position) {
        mCursor.moveToPosition(position);
        holder.mBookmarkChkBox.setChecked(mCursor.getString(VideoListFragment.COL_BOOKMARK_ID) != null);
    }

}

每次更新适配器光标时都会调用notifyDataSetChanged

ScrollBaseAdapter(父类):

public abstract class ScrollBaseAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    protected Cursor mCursor;

    public void swapCursor(Cursor cursor){
        mCursor = cursor;
        notifyDataSetChanged();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder holder;
        View view;
        if(checkViewTypeFlag(viewType, VIEW_TYPE_LOADING)){
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_loading, parent, false);
            holder = new ProgressViewHolder(view);
        }
        else{
            holder = myCreateViewHolder(parent, viewType);
        }
        return holder;
     }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if(checkViewTypeFlag(getItemViewType(position), VIEW_TYPE_LOADING)){
            return;
        }
        myBindViewHolder((VH) holder, position);
    }

}

注意:我已覆盖 父适配器类(ScrollBaseAdapter)中的OnCreateViewHolderOnBindViewViewHolder 子类(VideoAdapter类) 中调用这些方法的“my”版本,这些版本在父类中定义为abstract。但是在父OnCreateOnBind方法中没有任何花哨的东西,他们最终会调用孩子myMethods,即使是那些CheckBox不表现的项目预期

布局中的复选框

<CheckBox
    android:id="@+id/checkbox_bookmark_video"
    android:button="@null"
    android:drawableLeft="@drawable/selector_favorite"
    android:drawableStart="@drawable/selector_favorite"
    android:gravity="center"
    android:padding="@dimen/small_button_drawable_padding"
    android:layout_width="@dimen/small_button_size"
    android:layout_height="@dimen/small_button_size"
    />

selector_favorite

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/ic_favorite_on" />
    <item android:drawable="@drawable/ic_favorite_off" />
</selector>

更新 更确切地说,检查状态问题不可预测地发生。在某些情况下启动活动后,复选框显示为已选中,但有时它们显示为未选中,我必须向下滚动才能显示已选中的状态。即使在取消选中复选框的时间内,也会在复选框上评估setChecked(true)。出于某种原因,可能在回收站生命周期中的某些事件中,此后它将被取消选中。我无法理解。

1 个答案:

答案 0 :(得分:2)

问题出在复选框的布局属性中。我已将android:button设置为null并将android:drawableLeft设置为状态列表,而不是仅将button属性设置为状态列表。我这样做是为了解决一个android复选框错误,当通过button属性设置drawable属性时,无法将drawable与paddingLeftpaddingRight居中。不幸的是,使用drawableLeft设置复选框的drawable意味着在复选框上调用setChecked并不总是更新可绘制状态。