【问题标题】:CheckBox in List Adapter acts strange列表适配器中的复选框行为奇怪
【发布时间】:2015-10-04 12:08:59
【问题描述】:

我有一个列表适配器,每个项目都有一个复选框。我还可以选择从该列表中删除用户检查的所有项目。 应该删除所选项目的部分效果很好,但是.. 例如,如果我有

1. 0000
2. 5555
3. 9999

如果我检查 5555 和 9999,然后单击删除,它们会消失,但即使我没有按下它,也会检查 0000。

(historyList 是历史片段中的所有项目。listToRemove 只是选中的项目)

 @Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) 
{ 
    View view = inflater.inflate( R.layout.fragment_history, container, false );
    adapter = new PasswordAdapter( historyList );
    setListAdapter(adapter);
    ImageView removeButton = ( ImageView ) view.findViewById( R.id.removeButton );
    removeButton.setOnClickListener( new OnClickListener(){
        @Override
        public void onClick( View v )
        {
            if ( !listToRemove.isEmpty() )
            {
                listToRemove.clear();

                adapter.updateList( historyList );
            }
        }
    });

    return view;
}
...
...
...
@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final View result;

        if (convertView == null) 
        {
            result = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_list_item, parent, false);
        } 
        else 
        {
            result = convertView;
        }

        final Password item = getItem( position );

        ( (TextView) result.findViewById( R.id.historyPasswordTextView) ).setText(item.getPasswordString());
        ( (TextView) result.findViewById( R.id.historyDateTextView ) ).setText(item.getPasswordString());
        CheckBox checkBoxToRemove = (CheckBox) result.findViewById( R.id.removePasswordFromHistoryCheckBox ) ;
        checkBoxToRemove.setOnCheckedChangeListener( new OnCheckedChangeListener(){
                @Override
                public void onCheckedChanged( CompoundButton buttonView, boolean isChecked )
                {
                    if( isChecked )
                    {
                        listToRemove.add( item );
                    //  Log.d( "TAG", listToRemove.toString() );

                        for( int i=0; i<listToRemove.size(); i++)
                            Log.d("TAG","checked after add: "+ listToRemove.get(i).getPasswordString());
                    }
                    else
                    {
                        listToRemove.remove( item );
                        for( int i=0; i<listToRemove.size(); i++)
                            Log.d("TAG","checked after remove: "+ listToRemove.get(i).getPasswordString());
                    }

                }
            });

我错过了什么吗?

【问题讨论】:

  • 请分享您的代码....
  • @BVtp 您需要创建一个列表,列表项将是位置处的复选框 listitemclick 侦听器为复选框进行操作

标签: android list checkbox view adapter


【解决方案1】:

试试这样也许会奏效

     public View getView(int position, View convertView, ViewGroup parent) {
            final View result;
    ViewHolder holder;

            if (convertView == null) 
            {
    holder = new ViewHolder();
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_list_item, parent, false);

            holder. checkBoxToRemove = (CheckBox) convertView.findViewById( R.id.removePasswordFromHistoryCheckBox ) ;
    convertView.setTag(holder);
            } 
            else 
            {

    holder = (ViewHolder) convertView.getTag();
            }

            final Password item = getItem( position );


            holder .checkBoxToRemove.setOnCheckedChangeListener( new OnCheckedChangeListener(){
                    @Override
                    public void onCheckedChanged( CompoundButton buttonView, boolean isChecked )
                    {
                        if( isChecked )
                        {
                            listToRemove.add( item );
                        //  Log.d( "TAG", listToRemove.toString() );

                            for( int i=0; i<listToRemove.size(); i++)
                                Log.d("TAG","checked after add: "+ listToRemove.get(i).getPasswordString());
                        }
                        else
                        {
                            listToRemove.remove( item );
                            for( int i=0; i<listToRemove.size(); i++)
                                Log.d("TAG","checked after remove: "+ listToRemove.get(i).getPasswordString());
                        }

                    }
                });
return convertView;
}
     class ViewHolder {
            CheckBox checkBoxToRemove;
    }

然后在你的 getView 添加这个:

if(listToRemove.contains(item){
holder.checkBoxToRemove.setChecked(true);
}else{
holder.checkBoxToRemove.setChecked(false);
}

【讨论】:

  • 谢谢。我认为可能有问题。它向我显示了一些错误。顺便说一句,您在哪里返回 getView 的结果?
  • 我复制您的代码并进行编辑。现在检查我编辑的答案
  • 你添加了这个类 ViewHolder { CheckBox checkBoxToRemove; } 在你的适配器类中
【解决方案2】:

我认为你不应该在ListView 中使用复选框。您的问题可能是由于行视图被重用。我的意思是复选框可以来自上一个可见行(在您的示例中,删除后的第 0000 行,复选框可以是删除前的第 5555 行之一)。

我认为最好的方法是使用onItemClickListener。在您的onItemClick 方法中,您从适配器的listToRemove 添加或删除项目并调用adapter.notifyDataSetChange()

在您的getView 方法中,您根据listToRemove 列表绘制行。

【讨论】:

  • 我应该用什么替换复选框?
  • 您可以保留复选框但禁用用户交互。或者使用带有两个可绘制对象的图像视图用于选中和未选中。我的观点是不要使用OnCheckedChangeListener 来处理行选择。
  • 您也可以尝试使用 CheckedTextView 或实现 Checkable 的自定义视图。然后,您的适配器可以根据您维护的检查索引列表来管理重新检查适当的行,并在项目的检查状态发生更改时更新这些索引。
猜你喜欢
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 2020-08-29
  • 2010-12-13
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多