0

我有带有文本和复选框的列表视图。滚动列表视图时复选框的行为很奇怪。这似乎是一个回收问题。无论如何,我尝试了一些类似帖子中建议的各种选项,但没有一个对我有用。我尝试按照其中一篇文章的建议设置并获取标签位置,但运气不好。我在列表视图的活动文件中使用自定义适配器。以下是一些代码片段;活动类:

lv = (ListView) findViewById(R.id.itemdisplay_listview);
lv.setAdapter(new CustomAdapter(this, itemNames, tableNo));

自定义适配器:

private class CustomAdapter extends BaseAdapter {

        private List<String> mListItems;
        private LayoutInflater mLayoutInflater;
        ViewHolder holder;
        int a = 1;

        public CustomAdapter(Context context, List<String> arrayList,
                String table) {
            tableNumber = table;
            mListItems = arrayList;

            // get the layout inflater
            mLayoutInflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mListItems.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }

        private class ViewHolder {

            TextView itemName, quantity;
            CheckBox checkbox;
            ImageButton addBtn, minusBtn;

        }

        @Override
        public View getView(int position, View convertview, ViewGroup viewGroup) {

            // create a ViewHolder reference

            // check to see if the reused view is null or not, if is not null
            // then
            // reuse it
            if (convertview == null) {
                holder = new ViewHolder();

                convertview = mLayoutInflater.inflate(
                        R.layout.itemdisplay_list, null);

                holder.itemName = (TextView) convertview
                        .findViewById(R.id.itemdisplaylist_name);
                holder.addBtn = (ImageButton) convertview
                        .findViewById(R.id.itemdisplaylist_add);
                holder.minusBtn = (ImageButton) convertview
                        .findViewById(R.id.itemdisplaylist_minus);
                holder.quantity = (TextView) convertview
                        .findViewById(R.id.itemdisplaylist_quantity);
                holder.checkbox = (CheckBox) convertview
                        .findViewById(R.id.itemdisplaylist_cbox);

                // holder.checkbox.setTag(position);


                // the setTag is used to store the data within this view
                convertview.setTag(holder);
            } else {
                // the getTag returns the viewHolder object set as a tag to the
                // view
                holder = (ViewHolder) convertview.getTag();
            }

            holder.checkbox.setOnClickListener(checkListener);
            doneBtn.setEnabled(true);

            holder.minusBtn.setImageResource(R.drawable.minus);
            holder.quantity.setText(String.valueOf(a));
            holder.addBtn.setImageResource(R.drawable.add);
            holder.addBtn.setOnClickListener(addBtnClick);
            holder.minusBtn.setOnClickListener(minusBtnClick);

            String stringItem = mListItems.get(position);

            if (stringItem != null) {
                if (holder.itemName != null) {
                    // set the item name on the TextView
                    holder.itemName.setText(stringItem);
                }
            }

            // this method must return the view corresponding to the data at the
            // specified position.
            return convertview;

        }

        private OnClickListener checkListener = new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                /*doneBtn.setOnClickListener(doneBtnClick);*/
                View view = (View) v.getParent();

                CheckBox cb = (CheckBox) view
                        .findViewById(R.id.itemdisplaylist_cbox);
                TextView tv = (TextView) view
                        .findViewById(R.id.itemdisplaylist_name);
                TextView tv1 = (TextView) view
                        .findViewById(R.id.itemdisplaylist_quantity);
                if (cb.isChecked()) {
                    map.put(tv.getText().toString(), tv1.getText().toString());
                } else {
                    for (Iterator<Map.Entry<String, String>> it = map
                            .entrySet().iterator(); it.hasNext();) {

                        Map.Entry<String, String> entry = it.next();
                        String item = entry.getKey();
                        if ((tv.getText().toString()).equals(item)) {
                            it.remove();
                        }
                    }
                }

            }
        };

我已经挣扎了很长时间。请指教。谢谢。

4

5 回答 5

1

在调用setOnCheckedChangeListener之后,在自定义列表视图适配器中调用setChecked 。这样,您可以从回收视图中切断到旧侦听器的链接。

于 2014-12-17T09:43:20.647 回答
1

如果您有100 个 CB的数据,那么您还需要存储它们的checked/unchecked state. 假设一个包含 100 个元素的布尔数组CheckedStatus[100]。在 GetView 中做

 if(CheckedStatus[position] == true) {
 // check the check box
 } else {
 // uncheck it 
}.

该位置是在 GetView 函数中收到的位置

于 2013-09-26T04:28:25.003 回答
0

我的猜测是你被回收问题所困扰。
我建议您首先在 else 语句中使用以下内容删除侦听器

holder.checkbox.setOnCheckedChangeListener(null);

在您的代码中如下:

} else {
                // the getTag returns the viewHolder object set as a tag to the
                // view
                holder = (ViewHolder) convertview.getTag();
                holder.checkbox.setOnCheckedChangeListener(null);
            }
于 2013-09-26T04:13:09.277 回答
0

boolean checked变量添加到ViewHolder. 将其更改为checkListener. 然后在getView添加holder.checkbox.setChecked(holder.checked).

希望能帮助到你。

于 2013-09-26T02:37:22.413 回答
0

您将需要某种模型对象来保留复选框的状态,然后使用该模型而不是简单的字符串作为数据结构:

// Oversimplified, but adiquate for our purposes.
public class ItemModel
{
    public String text;
    public boolean isChecked;
}

然后,不是将一个字符串数组传递给适配器,而是传递一个ItemModels. 您需要的字符串将是文本参数,然后您必须将复选框值设置为该isChecked值。

isChecked一旦复选框的状态发生变化,剩下的就是改变值。if(convertView == null)在初始化holder.checkbox参数后,在块内的 getItem 方法内执行此操作。另外,请确保position在方法参数中创建变量final

这是代码:

holder.checkbox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() 
        {           
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
            {
                mListItems.get(position).isChecked = isChecked;

            }
        });

希望这可以帮助 :)

于 2013-09-26T02:38:29.280 回答