显然,“消失的选择”是有意设计的。这是一种叫做“触摸模式 http://developer.android.com/resources/articles/touch-mode.html“。我通读了该文档,但仍然不知道为什么他们认为这是一个好主意。我的猜测是,由于 Android 最初是为小屏幕设备设计的,他们希望你会用一个列表填满屏幕,然后然后,当用户单击某个项目时,移动到不同屏幕上的新列表。因此,用户不会意识到 Android 丢失了所选项目的跟踪。
但是,例如,如果您希望用户选择一个项目,然后在同一屏幕上显示有关该项目的信息,则这种行为非常烦人。如果选择消失,用户如何知道他们点击了什么(当然假设用户的注意力集中度像金鱼一样)?
一种可能的解决方案是将所有列表项更改为单选按钮。我不太喜欢这个解决方案,因为它浪费了屏幕空间。我宁愿只使用背景颜色来显示选择了哪个项目。到目前为止,我已经看到了一种解决方案,但它并不十分完整或通用。所以这是我的解决方案:
1. 在 XML 布局文件中
转到您的 ListView 元素和以下属性:android:choiceMode="singleChoice"
。我不完全确定它的作用(它本身不允许用户选择任何内容),但如果没有此属性,下面的代码将无法工作。
2.定义如下类
它用于跟踪所选项目,还允许您在 Java 中模拟按引用传递:
public class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int v) { value = v; }
}
3. 将以下代码放在某处
我假设你把它放在你的 Activity 中,但它实际上可以放在任何类中:
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. 使用该代码设置您的列表
例如:
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() 进行一些小的修改,您也可以支持多重选择,但您可能应该使用复选框。
Warning:该解决方案需要进一步开发。如果用户使用箭头键或按钮选择一个项目,该项目将not从 IntHolder 的角度进行选择。如果用户按下未标记的按钮(该按钮的名称是什么?“Enter”?),那么该项目将成为“正式”选择,但你会遇到另一个问题,因为如果用户再次使用箭头键,它看起来会有点像就像选择了两个项目一样。如果您弄清楚如何使 IntHolder 中的“内部选择”与“键盘选择”或任何名称保持同步,请发表评论。什么is无论如何,它打电话了?