【问题标题】:how to set choice mode single for listview with images如何为带有图像的列表视图设置选择模式
【发布时间】:2011-09-14 08:19:20
【问题描述】:

我有一个带有图像的列表视图。当我选择每个项目时,图像会更改为单击的图像。但是当我选择另一个项目时,两个图像都会更改。我只希望所选项目更改图像。它必须像单选按钮一样起作用单选模式。请帮助。

public class ProvierActivity extends Activity {
    private String text[] = { "BroadStripe-Cable (Seattle)", "BroadStripe-Digital (Seattle)",
        "BroadStripe-Cable (Seattle)", "Comcast king county south)", "BroadStripe-Cable (Seattle)",
        "Comcast king county south", "BroadStripe-Digital (Seattle)", "BroadStripe-Digital (Seattle)",
        "BroadStripe-Cable (Seattle)", "Comcast king county south" };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final ListView list = (ListView) findViewById(R.id.listview_id);

        list.setAdapter(new ArrayAdapter<String>(this, R.layout.list,
            R.id.title, text));

        list.setOnItemClickListener(new OnItemClickListener() {

        @Override
            public void onItemClick(AdapterView<?> arg0, View view,
                int position, long arg3) {
                // TODO Auto-generated method stub

                if (view.findViewById(R.id.img).getVisibility() == ImageView.VISIBLE) {
                    ImageView icon = (ImageView) view.findViewById(R.id.img);

                    icon.setImageResource(R.drawable.checked);
                }
            }
        });
    }
}

【问题讨论】:

标签: android android-listview


【解决方案1】:

这里推荐的解决方案是依赖内置的 ListView 的选择支持为其指定单选模式:

list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

那么你应该让你的列表项实现实现Checkable接口;这需要对布局的根视图进行一些自定义。假设它以 LinearLayout 作为根,实现可能如下所示:

public class MyListItem extends LinearLayout implements Checkable {

    public MyListItem(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyListItem(Context context) {
        super(context);
    }

    private boolean checked = false;

    private ImageView icon;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        icon = (ImageView)findViewById(R.id.img); // optimisation - you don't need to search for image view every time you want to reference it
    }
    @Override
    public boolean isChecked() {
        return checked;
    }

    @Override
    public void setChecked(boolean checked) {
        this.checked = checked;
        if (icon.getVisibility() == View.VISIBLE) {
            icon.setImageResource((checked) ? R.drawable.checked : R.drawable.unchecked);
        }
    }

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

当然,您的布局文件也应该更新为引用 MyListItem 类而不是 LinearLayout。

这可能是一种有点困难的方法,但它有一些好处,比如在重新创建活动时自动恢复选中的项目。

另一种选择是再次使用列表的选择模式并覆盖适配器的 getView 以了解是否检查了项目并相应地更新图像:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final ListView list = getListView();
    list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    list.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item,
            R.id.title, text) {
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = super.getView(position, convertView, parent);
            ImageView icon = (ImageView) v.findViewById(R.id.img);
            if (list.isItemChecked(position)) {
                icon.setImageResource(R.drawable.checked);
            } else {
                icon.setImageResource(R.drawable.unchecked);
            }
            return v;
        }
    });
}

但是这个版本有一些性能问题 - findViewById 和 setImageResource 是相对耗时的操作,所以你应该考虑使用一些缓存。我建议观看"The world of ListView" video 以了解有关此小部件的一些非常有用的提示。

后一种方法还将适配器绑定到引入了不必要的耦合的列表视图。

【讨论】:

  • 这会是一个更详细的更好答案,因为这似乎是一个非常常见的问题。
  • 不错的答案。非常优雅的解决方案。谢谢!
  • 相当不错的解决方案 :) 一个疑问:在第一种方法中,您为什么要在 setChecked() 方法中检查可见性:if (icon.getVisibility() == View.VISIBLE) {
【解决方案2】:
  1. 在列表视图中设置正确的选择模式。 setChoiceMode 根据您的需要。
  2. 根据状态创建一个可绘制选择器以使用您想要的图像。
  3. 将您的选择器设置为背景。

    android:background="@drawable/your_selector"
    

    仅供参考:

【讨论】:

  • 这是一个非常优雅的解决方案。对我来说,关键是意识到我需要在项目 LinearLayout 上使用 android:background="@drawable/your_selector" 而不是在 ListView 上使用 android:list_selector="@drawable/your_selector"
猜你喜欢
  • 2013-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
相关资源
最近更新 更多