RecyclerView:如何将CheckBox状态从ViewHolder绑定到onBindViewHolder?

时间:2017-12-11 02:54:54

标签: checkbox android-recyclerview android-viewholder

我有一个CardViews的RecyclerView列表。每个CardView都有一个CheckBox,用户可以选择/取消选择。初始选择启动Contextual Action Bar。 ArrayList of Integers用于保存复选框状态(选中或未选中)。滚动和复选框视图似乎正常工作。但是,当我单击一个复选框以取消选中它时,它仍会被选中,并且取消选择另一个CardView上的另一个复选框?我在这里错过了什么?

请注意,我不想在onBindViewHolder中设置ClickListener。

MainActivity.java

public class MainActivity extends AppCompatActivity implements
    RecyclerItemClickListener {

    private ArrayList<ListItem> allList; 
    boolean isMultiSelect = false; // for the Contextual Action Bar status
    private ActionMode mActionMode;
    ArrayList<ListItem> multiselect_list = new ArrayList<>();
    private ArrayList<Integer> checkedListItems = new ArrayList<>();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    ...

    // method from the Adapter, the ItemHolder's onClick()
    public void onCheckBoxClick(View view, int position) {

    if (!isMultiSelect) {
        multiselect_list = new ArrayList<>();
        isMultiSelect = true;

        if (mActionMode == null) {
            mActionMode = startSupportActionMode(actionModeCallback);                
        }
    }
    multi_select(position);
}

public void multi_select(int position) {

    if (mActionMode != null) {
        // If a CardView with a CheckBox already selected is clicked on, then the
        // Checkbox is unselected, the position is removed from the multiselect_list
        // and the size of the list is decremented by +1.
        if (multiselect_list.contains(allList.get(position))) {
            multiselect_list.remove(allList.get(position));
        }
        else {
            // If an empty CheckBox on a CardView is clicked on, then the position is added to the
            // multiselect_list and the size of the list is incremented by +1.
            multiselect_list.add(allList.get(position));
        }           
        if (multiselect_list.size() == 1) {
            mActionMode.setTitle("1 selected");
        }
        else if (multiselect_list.size() >= 2) {
            mActionMode.setTitle(multiselect_list.size() + " selected");
        }
        else if (multiselect_list.size() == 0) {
            mActionMode.finish();                
        }
        refreshAdapter();
    }
}

public void refreshAdapter() {
    adapter.selectedItemsList = multiselect_list;
    adapter.mListItems = allList;
    adapter.notifyDataSetChanged();
}

private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {

    Menu context_menu;

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {

        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.menu_action_mode, menu);
        context_menu = menu;
        return true;
    }
    ...
} 

Adapter.java

public class MyRecylerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

public ArrayList<ListItem> mListItems;
private Context mContext;
private RecyclerItemClickListener recyclerItemClickListener; 
public ArrayList<ListItem> selectedItemsList = new ArrayList<>();

public MyRecylerAdapter(Context context, ArrayList<ListItem> listItems, ArrayList<ListItem> selectedList) {
    this.mContext = context;
    this.mListItems = listItems;
    this.selectedItemsList = selectedList;
} 

private class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private CheckBox chkSelected;

    private ItemHolder(final View itemView) {
        super(itemView);

        chkSelected = (CheckBox) itemView.findViewById(R.id.chkSelected);
        chkSelected.setOnClickListener(this); 
    }  

    public void onClick(View v) {

        int adapterPos = getAdapterPosition();

        // send data to MainActivity() for starting CAB.
        if (recyclerItemClickListener !=null) {
            recyclerItemClickListener.onCheckBoxClick(v, adapterPos);
        }

        if (((CheckBox)v).isChecked()) {
            checkedListItems.add(adapterPos);
        }
        else {
            checkedListItems.remove(adapterPos);
        } 
    }    

    void bind(int position) { 

        if (checkedListItems.contains(position)) {
            chkSelected.setChecked(true);
        }
        else {
            chkSelected.setChecked(false);
        }    
    }
}    

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false);
    final ItemHolder itemHolder = new ItemHolder(view);
    ...
    return itemHolder;
}

public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

    final ListItem listItem = mListItems.get(position);
    final ItemHolder itemHolder = (ItemHolder) holder;

    itemHolder.bind(position);    
    ...
}

1 个答案:

答案 0 :(得分:1)

在Adpater中声明一个整数的ArrayList

ArrayList<Integer> checkedItems = new ArrayList();

在绑定函数中

void bind(int position) { 

    if (checkedItems.contains(position)) {
        chkSelected.setChecked(true);
    }
    else {
        chkSelected.setChecked(false);
    }
}

在OnBindviewholder中添加以下代码

CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int adapterPos = getAdapterPosition();
        if(isChecked) {
            checkedItems.add(Integer.valueOf(adapterPos));
        }else {
            checkedItems.remove(Integer.valueOf(adapterPos));
        }
    }
}