如何为带有图像的列表视图设置单一的选择模式

时间:2011-09-14 08:19:21

标签: android android-listview

我有一个带有图像的列表视图。当我选择每个项目时,图像会变为点击的图像。但是当我选择另一个项目时,两个图像都会发生变化。我只想要选择的项目来更改图像。它必须像单选按钮一样运行单选模式.pls帮助。

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

2 个答案:

答案 0 :(得分:37)

这里推荐的解决方案是依靠内置的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以了解有关此小部件的一些非常有用的提示。

后一种方法还将适配器绑定到listview,这会引入不必要的耦合。

答案 1 :(得分:5)

  1. 在列表视图中设置正确的选择模式。根据您的需要setChoiceMode
  2. 根据状态创建一个可绘制的选择器以使用您想要的图像。
  3. 将选择器设置为背景。

    android:background="@drawable/your_selector"
    

    仅供参考: