我有一个包含项目的列表视图,在用户选择一个项目亮起后,它会恢复正常。有没有办法让它在用户选择ListView中的项目时保持选中状态并突出显示?
答案 0 :(得分:15)
显然,“消失的选择”是设计上的;它叫做“touch mode”。我仔细阅读了该文件,但我仍然不知道为什么他们认为这是一个好主意。我的猜测是,由于Android最初是为小屏幕设备设计的,他们希望你用一个列表填充屏幕,然后当用户点击一个项目时,移动到另一个屏幕上的新列表。因此,用户不会意识到Android丢失了对所选项目的跟踪。
但是,例如,如果您希望用户选择项目然后在同一屏幕上显示有关该项目的信息,则此行为非常烦人。如果选择消失,用户应该如何知道他们点击了什么(当然假设用户有金鱼的注意力范围)?
一种可能的解决方案是将所有列表项更改为单选按钮。我真的不喜欢这个解决方案,因为它浪费了屏幕空间。我宁愿只使用背景颜色来显示选择了哪个项目。到目前为止,我已经看到了一种解决方案,但它并不完全或一般。所以这是我的解决方案:
转到ListView元素和以下属性:android:choiceMode="singleChoice"
。我不完全确定它的作用(本身,它不允许用户选择任何东西)但是没有这个属性,下面的代码不起作用。
它用于跟踪所选项目,还允许您在Java中模拟传递引用:
public class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int v) { value = v; }
}
我会假设你把它放在你的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()
以更改所选项目的背景。
例如:
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的角度选择不。如果用户按下未标记的按钮(该按钮的名称是什么?“输入”?),那么该项目将被“正式”选中,但之后又出现了另一个问题,因为如果用户再次使用箭头键,它会有点像喜欢选择两个项目。如果您弄清楚如何使IntHolder中的“内部选择”与“键盘选择”或其所谓的“键盘选择”保持同步,请发表评论。无论如何 它被调用了什么?
答案 1 :(得分:2)
ListView中有一个名为listSelector的属性:
Drawable用于表示列表中当前选定的项目。
http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:listSelector
编辑
要确保ListView
保持选中状态,您应该
①通过xml或以编程方式设置视图的属性choiceMode
。
②使用使用实现Checkable
界面的视图的适配器,例如CheckedTextView
(simple_list_item_single_choice
布局内部)。
档案TestActivity.java
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 :(得分:2)
这是一个比Qwertie更简单的解决方案:
不要依赖于给定的选择机制。自己动手。
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
答案 3 :(得分:-1)
只需将其添加到列表视图布局
即可 android:listSelector="@drawable/selector_expandable_listview"
android:drawSelectorOnTop="true"
答案 4 :(得分:-1)
使用Selector.XML文件和此代码:
//SetOnClickListner to catch Events
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
}
});
答案 5 :(得分:-1)
只需将其添加到ListView:
android:listSelector="@color/my_color"
答案 6 :(得分:-3)
这个答案正在尝试这个
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long arg3)
{
for(int a = 0; a < parent.getChildCount(); a++)
{
parent.getChildAt(a).setBackgroundColor(Color.TRANSPARENT);
}
view.setBackgroundColor(Color.GREEN);
}