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

发布于 2024-09-25 03:47:38 字数 3191 浏览 7 评论 0原文

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

我已经使适配器项扩展为 Checkable,但 getCheckedItemPositions() 仍然返回 false 数组。

我想我做错了一些基本的事情,但到目前为止我还无法找到多个选择 ListView 的示例,其中适配器不是使用默认布局进行多个选择的 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;
}
}

I have a ListView with a custom adapter. The ListView allows multiple select, but somehow it's not recognising when an item is selected.

I've already made the adapter items extend Checkable, but still the getCheckedItemPositions()returns an array of falses.

I guess there's something fundamental I'm doing wrong, but I have been unable so far to find examples of multiple select ListViews where the adapter was not an ArrayAdapter using the default layout for multiple selects.

Any help would be much appreciated.

Code is below:

Main class:

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

tca = new TextCardAdapter(mInflater);
listView.setAdapter(tca);

Adapter:

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;
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甲如呢乙后呢 2024-10-02 03:47:46

我有类似的问题。我的列表项视图是一个 RealativeLayout,其中 LinearLayout 包含一个 CheckBox 和一个 TextView。在我将 CheckBox.focusable 设置为 false 之前,不会调用 onItem...Listener。此外,适配器中的对象不应该是可检查的,而是用作列表项布局的视图。

I had a similar problem. My list item view is a RealativeLayout with a LinearLayout containing a CheckBox and a TextView. No onItem...Listener was called until I did set the CheckBox.focusable to false. Furthermore not the objects in the adapter should be Checkable but the views used as the layout for the list item.

停滞 2024-10-02 03:47:43

尝试一下:

  1. listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

  2. holder.checkbox.setFocusable(false);

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

Just have a try:

  1. listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

  2. holder.checkbox.setFocusable(false);

  3. I think that is the listView's sub item view shoudld implements the Checkable interface, that means the converted View(convertView) should have all the method of Checkable.

离不开的别离 2024-10-02 03:47:43

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

I had a problem like this once. It has something to do with the fact that you have a view on the adapter that is selectable causing the parent to ignore it. Removing it allows you to select the row of the listview again. What you've created is basically a button on a button, android does not like that :-(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文