ListView控件:只有setItemChecked支持标准ArrayAdapter - 当使用自定义ArrayAdapter也不行?自定义、控件、标准、ListView

2023-09-12 08:36:39 作者:敷衍

这是很奇怪的。

在我使用的标准ArrayAdapter的一个ListView调用setItemChecked工程确定

但使用由ArrayAdapter它的自定义时,不会。

会是什么原因呢?这是一个错误?还是我失去了一些东西?

 公共类Test_Activity延伸活动{

    / **第一次创建活动时调用。 * /
    私人列表<型号:GT;清单;
    私人的ListView LVIEW;

    公共无效的onCreate(包冰柱){
    super.onCreate(冰柱);
    //创建一个字符串数组,将被投入到我们的ListActivity
    的setContentView(R.layout.main);
    LVIEW =(ListView控件)findViewById(R.id.ListView01);
    lView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

    表= getModel();

    //与此适配器setItemChecked工程确定
    lView.setAdapter(新ArrayAdapter<型号>(这一点,
        android.R.layout.simple_list_item_multiple_choice,列表));


  // ***********
    //问题:与此适配器它不检查屏幕上的任何项目
    // ArrayAdapter<型号:GT;适配器=新Test_Class1(这一点,清单);
    // lView.setAdapter(适配器);



    }

    私人列表<型号:GT; getModel(){
       名单<型号:GT;名单=新的ArrayList<型号>();
       list.add(获得(0));
       list.add(获得(1));
       list.add(获得(2));
       list.get(1).setSelected(真正的);
       模型米= list.get(1);
       list.add(获得(3));
       list.add(获得(4));
       list.add(获得(5));
       list.add(获得(6));
       list.add(获得(7));
       //最初选择的项目之一
       返回列表;
    }

    私模的get(String s)将{
       返回新模式(S);
    }

    @覆盖
    公共布尔onCreateOptionsMenu(功能菜单){
       MenuInflater充气= getMenuInflater();
       inflater.inflate(R.menu.results_screen_option_menu,菜单);
       返回true;
    }

    / **
     * @Category OptionsMenu
     * /
    @覆盖
 公共布尔onOptionsItemSelected(菜单项项){
    开关(item.getItemId()){
    案例R.id.select_all:{

        INT大小= lView.getAdapter()getCount将()。

        的for(int i = 0; I< =大小;我++){

            //************************** 问题
        lView.setItemChecked(我,真正的); //选择项目只针对标准ArrayAdapter

    Log.i(XXX,循环+ I);
        }
    }
        返回true;
    案例R.id.select_none:
        返回true;
    }
    返回false;
    }
}
 
使用复选框选择行

// --------------------------------------------- ---------------

 公共类Test_Class1扩展ArrayAdapter<型号:GT; {

    私人最终名单,其中,型号>清单;
    私人最终活动范围内;

 公共Test_Class1(活动背景下,列表与LT;型号>列表){
    超(背景下,R.layout.rowbuttonlayout2,清单);
    this.context =背景;
    this.list =清单;
    }

  静态类ViewHolder {
    受保护的TextView文本;
    保护复选框复选框;
    }

    @覆盖
 公共查看getView(INT位置,查看convertView,ViewGroup中父){
    查看查看= NULL;
    Log.i(XXX, - > getView+位置);
    如果(convertView == NULL){
        LayoutInflater充气= context.getLayoutInflater();
        鉴于= inflator.inflate(R.layout.rowbuttonlayout,NULL);
        最后ViewHolder viewHolder =新ViewHolder();
        viewHolder.text =(TextView中)view.findViewById(R.id.label);
        viewHolder.checkbox =(复选框)view.findViewById(R.id.check);
        viewHolder.checkbox
            .setOnCheckedChangeListener(新CompoundButton.OnCheckedChangeListener(){

            @覆盖
            公共无效onCheckedChanged(CompoundButton buttonView,
                布尔器isChecked){
                模型元素=(模型)viewHolder.checkbox
                    .getTag();
                Log.i(XXX, - > onCheckedChanged);
                element.setSelected(buttonView.isChecked());
                Log.i(XXX,&所述;  -  onCheckedChanged);

            }
            });
        view.setTag(viewHolder);
        viewHolder.checkbox.setTag(list.get(位置));
    } 其他 {
        鉴于= convertView;
        ((ViewHolder)view.getTag())checkbox.setTag(list.get(位置))。
    }
    ViewHolder支架=(ViewHolder)view.getTag();
    holder.text.setText(list.get(位置).getName());
    Log.i(XXX,holder.checkbox.setChecked:+位置);

    holder.checkbox.setChecked(list.get(位置).isSelected());
    Log.i(XXX,<  -  getView+位置);

    返回查看;
    }

}
 

解决方案

您行布局必须是可检查 setItemChecked()工作,在这种情况下,Android将管理要求 setChecked()可检查的用户点击上的行。你可能并不需要建立自己的 OnCheckedChangeListener

有关更多信息,请参阅:

ListView使用CheckedText在自定义视图 CHOICE_MODE_MULTIPLE 多项选择列表,自定义视图? http://www.marvinlabs.com/2010/10/custom-listview-ability-check-items/ http://tokudu.com/2010/android-checkable-linear-layout/ http://alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml

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 not.

What would be the reason? Is this a bug? Or am I missing something?

public class Test_Activity extends Activity {

    /** Called when the activity is first created. */
    private List<Model> list;
    private ListView lView;

    public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    // Create an array of Strings, that will be put to our ListActivity
    setContentView(R.layout.main);
    lView = (ListView) findViewById(R.id.ListView01);
    lView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

    list = getModel();

    //with this adapter setItemChecked works OK
    lView.setAdapter(new ArrayAdapter<Model>(this,
        android.R.layout.simple_list_item_multiple_choice, list));


  //**************************
    //PROBLEM: with this adapter it does not check any items on the screen
    // ArrayAdapter<Model> adapter = new Test_Class1(this, list);
    // lView.setAdapter(adapter);



    }

    private List<Model> getModel() {
       List<Model> list = new ArrayList<Model>();
       list.add(get("0"));
       list.add(get("1"));
       list.add(get("2"));
       list.get(1).setSelected(true);
       Model m = list.get(1);
       list.add(get("3"));
       list.add(get("4"));
       list.add(get("5"));
       list.add(get("6"));
       list.add(get("7"));
       // Initially select one of the items
       return list;
    }

    private Model get(String s) {
       return new Model(s);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
       MenuInflater inflater = getMenuInflater();
       inflater.inflate(R.menu.results_screen_option_menu, menu);
       return true;
    }

    /**
     * @category OptionsMenu
     */
    @Override
 public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.select_all: {

        int size = lView.getAdapter().getCount();

        for (int i = 0; i <= size; i++) {

            //************************** PROBLEM
        lView.setItemChecked(i, true); // selects the item only for standard ArrayAdapter

    Log.i("xxx", "looping " + i);
        }
    }
        return true;
    case R.id.select_none:
        return true;
    }
    return false;
    }
}

//------------------------------------------------------------

public class Test_Class1 extends ArrayAdapter<Model> {

    private final List<Model> list;
    private final Activity context;

 public Test_Class1(Activity context, List<Model> list) {
    super(context, R.layout.rowbuttonlayout2, list);
    this.context = context;
    this.list = list;
    }

  static class ViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
    }

    @Override
 public View getView(int position, View convertView, ViewGroup parent) {
    View view = null;
    Log.i("xxx", "-> getView " + position);
    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        view = inflator.inflate(R.layout.rowbuttonlayout, null);
        final ViewHolder viewHolder = new ViewHolder();
        viewHolder.text = (TextView) view.findViewById(R.id.label);
        viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check);
        viewHolder.checkbox
            .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
                Model element = (Model) viewHolder.checkbox
                    .getTag();
                Log.i("xxx", "-> onCheckedChanged");
                element.setSelected(buttonView.isChecked());
                Log.i("xxx", "<- onCheckedChanged");

            }
            });
        view.setTag(viewHolder);
        viewHolder.checkbox.setTag(list.get(position));
    } else {
        view = convertView;
        ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
    }
    ViewHolder holder = (ViewHolder) view.getTag();
    holder.text.setText(list.get(position).getName());
    Log.i("xxx", "holder.checkbox.setChecked: " + position);

    holder.checkbox.setChecked(list.get(position).isSelected());
    Log.i("xxx", "<-  getView " + position);

    return view;
    }

}

解决方案

Your row layout needs to be Checkable for setItemChecked() to work, in which case Android will manage calling setChecked() on your Checkable as the user clicks on the row. You would not need to be setting up your own OnCheckedChangeListener.

For more, see:

ListView with CHOICE_MODE_MULTIPLE using CheckedText in a custom view Multiple choice list with custom view? http://www.marvinlabs.com/2010/10/custom-listview-ability-check-items/ http://tokudu.com/2010/android-checkable-linear-layout/ http://alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml