首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ListView是否保持选中状态?

ListView是否保持选中状态?
EN

Stack Overflow用户
提问于 2010-06-24 23:20:42
回答 7查看 15.7K关注 0票数 10

我有一个充满项目的列表视图,在用户选择一个项目后,它会亮起,然后它就会恢复正常。有没有办法让它在用户选择my ListView中的项目时保持选中并突出显示?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-06-16 09:42:07

显然,“消失的选择”是设计出来的;它被称为"touch mode“。我通读了那份文件,但我仍然不知道为什么他们认为这是一个好主意。我的猜测是,由于Android最初是为小屏幕设备设计的,他们希望你在屏幕上填满一个列表,然后,当用户点击一个项目时,移动到另一个屏幕上的新列表。因此,用户不会意识到Android失去了对所选项目的跟踪。

但是,例如,如果您希望用户选择一个项目,然后在同一屏幕上显示有关该项目的信息,则此行为非常恼人。如果选择消失了,用户如何知道他们点击了什么(当然,假设用户具有金鱼的注意力持续时间)?

一种可能的解决方案是将所有列表项更改为单选按钮。我真的不喜欢这个解决方案,因为它浪费了屏幕空间。我更愿意使用背景颜色来显示选择了哪一项。到目前为止,我已经看到了一种解决方案,但它并不是完全或通用的。所以这是我的解决方案:

1.在XML布局文件中

转到您的ListView元素和以下属性:android:choiceMode="singleChoice"。我不完全确定这是做什么的(它本身不允许用户选择任何东西),但是如果没有这个属性,下面的代码就不能工作。

2.定义以下类

它用于跟踪所选项目,还允许您在Java中模拟按引用传递:

代码语言:javascript
复制
public class IntHolder {
    public int value;
    public IntHolder() {}
    public IntHolder(int v) { value = v; } 
}

3.将以下代码放在某个位置

我假设你把它放在你的活动中,但实际上它可以放在任何班级中:

代码语言:javascript
复制
static void setListItems(Context context, AdapterView listView, List listItems, final IntHolder selectedPosition)
{
    setListItems(context, listView, listItems, selectedPosition, 
                 android.R.layout.simple_list_item_1, 
                 android.R.layout.simple_spinner_dropdown_item);
}
static void setListItems(Context context, AdapterView listView, List listItems, final IntHolder selectedPosition, 
                         int list_item_id, int dropdown_id)
{
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> list, View lv, int position, long id) {
            selectedPosition.value = position;
        }
    });
    ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context, list_item_id, listItems) { 
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View itemView = super.getView(position, convertView, parent);
            if (selectedPosition.value == position)
                itemView.setBackgroundColor(0xA0FF8000); // orange
            else
                itemView.setBackgroundColor(Color.TRANSPARENT);
            return itemView;
        }
    };
    adapter.setDropDownViewResource(dropdown_id);
    listView.setAdapter(adapter);
}

这段代码做了两件事:它将你的列表项(例如List<String>)附加到你的ListView,并且它用一些改变选定项背景的代码覆盖了ArrayAdapter.getView()

4.使用该代码设置您的列表

例如:

代码语言:javascript
复制
ListView _list;
IntHolder _selectedItem = new IntHolder(-1); // nothing selected at first

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    _list = (ListView)findViewById(R.id.list);
    List<String> items = Arrays.asList("Item 1", "Item 2", "Item 3");
    setListItems(this, _list, items, _selectedItem);
}

就这样!以上假设您想要单项选择。通过对getView()进行一些小的修改,我想您也可以支持多选,但是您可能应该使用复选框。

警告:此解决方案需要进一步开发。如果用户使用箭头键或按钮来选择一个项目,则该项目将不会从IntHolder的角度进行选择。如果用户按下未标记的按钮(该按钮的名称是什么?"Enter"?)然后,该项目将变为“正式”选择,但您还会遇到另一个问题,因为如果用户再次使用箭头键,看起来就像选择了两个项目。如果你知道如何使IntHolder中的“内部选择”与“键盘选择”或其他名称保持同步,请留下评论。不管怎么说,它叫什么?

票数 15
EN

Stack Overflow用户

发布于 2013-09-03 16:47:54

ListView中有一个名为listSelector的属性:

可绘制,用于指示列表中当前选定的项。

http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:listSelector

在注释后编辑

为了确保ListView保持选中状态,您应该

1通过xml或以编程方式设置视图的属性choiceMode

2使用使用实现Checkable接口的视图的适配器,如CheckedTextView (在simple_list_item_single_choice布局中)。

文件TestActivity.java

代码语言:javascript
复制
public class TestActivity extends Activity {

    private static final int SINGLE_CHOICE = android.R.layout.simple_list_item_single_choice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);

        String[] items = {"test 1", "test 2", "test 3"};
        ListAdapter adapter = new ArrayAdapter<String>(this, SINGLE_CHOICE, items);
        ListView list = (ListView) findViewById(R.id.testList);
        list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        list.setAdapter(adapter);
    }
}
票数 2
EN

Stack Overflow用户

发布于 2014-02-21 21:51:41

这里有一个比Qwertie更简单的解决方案:

不要依赖给定的选择机制。自己的事情自己做。

代码语言:javascript
复制
View mSelectedItemView = null; //class member variable
View mTouchedItemView = null; //class member variable

ListView v = (ListView) getActivity().findViewById(R.id.listView);
// select on click
v.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapter,
            View clickedViewItem, int position, long id) {
        if (mSelectedItemView != null)
            selectedItemView.setBackgroundColor(Color.WHITE);
        clickedViewItem.setBackgroundColor(Color.YELLOW);
        mSelectedItemView = clickedViewItem;
    }
});
// highlight on touch
v.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v instanceof ListView) {
            ListView listView = (ListView) v;
            // Find the child view that was touched (perform a
            // hit test)
            Rect rect = new Rect();
            int childCount = listView.getChildCount();
            int[] listViewCoords = new int[2];
            v.getLocationOnScreen(listViewCoords);
            int x = (int) event.getRawX() - listViewCoords[0];
            int y = (int) event.getRawY() - listViewCoords[1];
            View child;
            for (int i = 0; i < childCount; i++) {
                child = listView.getChildAt(i);
                child.getHitRect(rect);
                if (rect.contains(x, y)) {
                    View touchedView = child;
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        touchedView
                                .setBackgroundColor(Color.RED);
                        mTouchedItemView = touchedView;
                    } else if (event.getAction() == MotionEvent.ACTION_UP) {
                        mTouchedItemView 
                                .setBackgroundColor(Color.WHITE);
                    }
                }
            }
        }
        return false;
    }
});

此外,此方法仅处理单击,如果用户使用箭头键,则此方法将不起作用。

免责声明:触摸后取消高亮显示不可靠。

感人的部分请访问ozik.dev:Get Item from ListView only with OnTouchListener

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3111354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档