具有多个选择和自定义适配器的Android ListView

具有多个选择和自定义适配器的Android ListView,android,listview,listadapter,multiple-select,Android,Listview,Listadapter,Multiple Select,我有一个带有自定义适配器的列表视图。ListView允许多次选择,但不知何故,它无法识别何时选择了某个项目 我已经使适配器项扩展为可检查,但是getCheckedItemPositions()仍然返回一个false数组 我想我做错了一些基本的事情,但到目前为止,我无法找到多个选择列表视图的示例,其中适配器不是使用默认布局进行多个选择的ArrayAdapter 任何帮助都将不胜感激 代码如下: 主要类别: listView = (ListView) findViewById(R.id.cardli

我有一个带有自定义适配器的
列表视图
ListView
允许多次选择,但不知何故,它无法识别何时选择了某个项目

我已经使适配器项扩展为可检查,但是
getCheckedItemPositions()
仍然返回一个false数组

我想我做错了一些基本的事情,但到目前为止,我无法找到多个选择列表视图的示例,其中适配器不是使用默认布局进行多个选择的ArrayAdapter

任何帮助都将不胜感激

代码如下:

主要类别:

listView = (ListView) findViewById(R.id.cardlist);

tca = new TextCardAdapter(mInflater);
listView.setAdapter(tca);
适配器:

public class TextCardAdapter extends BaseAdapter {
private int count = 0;
private List<CheckableCard> cardList = new ArrayList<CheckableCard>();
private LayoutInflater mInflater;

public TextCardAdapter(LayoutInflater inflater) {
    this.mInflater = inflater;
}

@Override
public int getCount() {
    return count;
}

@Override
public Object getItem(int position) {
    return cardList.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.textlayout_row, null, false);
        convertView.setClickable(true);

        holder = new ViewHolder();
        holder.text = (TextView) convertView.findViewById(R.id.card_name);
        holder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final CheckableCard card = cardList.get(position);

    holder.text.setText(card.card.toString());
    holder.checkbox.setChecked(card.isChecked());
    holder.checkbox.setOnClickListener(card.checkListener);
    convertView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            card.checkListener.onClick(v);
            holder.checkbox.setChecked(card.isChecked());
        }
    });

    return convertView;
}

public void add(Card card) {
    cardList.add(new CheckableCard(card));
    count++;
    notifyDataSetChanged();
}

public void addAll(Collection<Card> cardColl) {
    for (Card c : cardColl)
        add(c);
}

public void removeAll() {
    count = 0;
    cardList.clear();
    notifyDataSetChanged();
}

public Card getCard(int position) {
    CheckableCard cc = (CheckableCard) getItem(position);
    if (cc == null) return null;
    return cc.card;
}

public class CheckableCard implements Checkable {
    private boolean checked = false;
    public final Card card;
    public final OnClickListener checkListener;

    public CheckableCard(Card card) {
        this.card = card;
        checkListener = new OnClickListener() {

            @Override
            public void onClick(View v) {
                toggle();
            }
        };
    }

    @Override
    public boolean isChecked() {
        return checked;
    }

    @Override
    public void setChecked(boolean checked) {
        this.checked = checked;
    }

    @Override
    public void toggle() {
        checked = !checked;
    }

}

static class ViewHolder {
    TextView text;
    CheckBox checkbox;
}
}
公共类TextCardAdapter扩展了BaseAdapter{
私有整数计数=0;
private List cardList=new ArrayList();
私人停车场;
公共文本卡适配器(充气机){
this.mInflater=充气机;
}
@凌驾
public int getCount(){
返回计数;
}
@凌驾
公共对象getItem(int位置){
返回卡片列表。获取(位置);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
最终持票人;
if(convertView==null){
convertView=mInflater.inflate(R.layout.textlayout_行,null,false);
convertView.setClickable(真);
holder=新的ViewHolder();
holder.text=(TextView)convertView.findViewById(R.id.card\u name);
holder.checkbox=(checkbox)convertView.findViewById(R.id.checkbox);
convertView.setTag(支架);
}否则{
holder=(ViewHolder)convertView.getTag();
}
最终可检查卡片=卡片列表。获取(位置);
holder.text.setText(card.card.toString());
holder.checkbox.setChecked(card.isChecked());
holder.checkbox.setOnClickListener(card.checkListener);
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
card.checkListener.onClick(v);
holder.checkbox.setChecked(card.isChecked());
}
});
返回视图;
}
公共作废添加(卡片){
卡片列表。添加(新的可检查卡片(卡片));
计数++;
notifyDataSetChanged();
}
公共无效添加所有(收集卡){
用于(卡c:cardColl)
添加(c);
}
公共无效删除所有(){
计数=0;
cardList.clear();
notifyDataSetChanged();
}
公共卡getCard(内部位置){
CheckableCard cc=(CheckableCard)getItem(位置);
如果(cc==null)返回null;
返回抄送卡;
}
公共类CheckableCard实现可检查{
私有布尔值选中=false;
公共最终卡;
公共最终onclick监听器checkListener;
公共支票卡(信用卡){
这张卡=卡片;
checkListener=newonclicklistener(){
@凌驾
公共void onClick(视图v){
切换();
}
};
}
@凌驾
公共布尔值已检查(){
退货检查;
}
@凌驾
公共void setChecked(布尔值已选中){
this.checked=checked;
}
@凌驾
公共无效切换(){
选中=!选中;
}
}
静态类视窗夹{
文本查看文本;
复选框;
}
}
试试看:

  • listView.setChoiceMode(listView.CHOICE\u MODE\u MULTIPLE)

  • holder.checkbox.setFocusable(false)

  • 我认为listView的子项视图应该实现Checkable接口,这意味着转换后的视图(convertView)应该具有所有Checkable方法


  • 我曾经遇到过这样的问题。这与您在适配器上有一个可选择的视图这一事实有关,导致父级忽略它。删除它允许您再次选择listview的行。您创建的基本上是一个按钮上的按钮,android不喜欢这样:-(

    我也有类似的问题。我的列表项视图是一个RealativeLayout,带有一个包含复选框和文本视图的LinearLayout。在我将复选框设置为false之前,没有调用onItem…侦听器。可聚焦为false。此外,适配器中的对象不应该是可检查的,而是用作列表项布局的视图。

    我找到了一个通用的me在一个类似的stackoverflow问题()中解决您的问题的方法:您找到这个问题的解决方案了吗?我的解决方案最终是存储可检查卡片的列表,在检索所有已检查的卡片时,遍历列表并返回返回isChecked()的卡片如是。@Pingless请检查此答案,它可能会有帮助: