ListView: setItemChecked only works with standard ArrayAdapter - does NOT work when using customized ArrayAdapter?

前端 未结 4 1830
遇见更好的自我
遇见更好的自我 2020-12-04 16:35

This is really weird.

When I use the standard ArrayAdapter for a ListView calling setItemChecked works OK

But when using a custom made ArrayAdapter it does n

4条回答
  •  一向
    一向 (楼主)
    2020-12-04 17:17

    Checkable is a learning curve I prefer not to take right now. You can set and unset the CheckBox manually in the Activities' OnItemClickListener. Maintain a boolean isChecked transient variable in the MyObject list in the ArrayAdapter.

    public void onItemClick(AdapterView av, View v, int position, long arg3) {
        final ListView listView = (ListView) findViewById(android.R.id.list);
        MyObject item = (MyObject) listView.getItemAtPosition(position);
        item.isChecked = !item.isChecked;
        if(item.isChecked)
            addItem(item);
        else
            removeItem(item);
    }  
    

    To account for users clicking the CheckBox itself; use the same addItem(item)/removeItem(item) logic in your custom array adapter's getView implementation, in the CheckBox's OnClickListener.

    public View getView(int position, View convertView, ViewGroup viewGroup) {
            CheckBox cb = null;
            if (convertView == null) {
                if(inflater == null) //cache to avoid reconstructing for each view
                inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView =inflater.inflate(R.layout.list_item_text_right_checkmark, null);
    
                CheckBox cb = (CheckBox) convertView.findViewById(R.id.check);
                cb.setChecked((list.get(position).isChecked));
                cb.setTag(list.get(position);
                public void onClick(View v) {
                    if(v instanceof CheckBox) {
                        CheckBox cb = (CheckBox) v;
                        if(cb.isChecked()) //verify boolean logic here!!!
                            activityRef.get().addItem(cb.getTag()); //WeakReference to activity
                        else
                            activityRef.get().removeItem(cb.getTag());
    
                    }
                });
        } else cb = (CheckBox) convertView.findViewById(R.id.check);
        cb.setChecked((list.get(position).isChecked));
    ...
    }
    

    Calling CheckBox::setChecked() is the key here.
    This seems to do the trick as long as your array adapter can assume the same activity, and your array adapter can assume the same list item xml definition in res/layout/.

    checkable list item XML:

    
    
    
      
    
      
    
    

    If you need to check some of your CheckBoxs initially, just set your isChecked members in your MyObject prior to inflating.

提交回复
热议问题