ListView项目不会保持“select”

我想改变一个列表视图项目的背景,当用户点击它。 有点像蜂窝设置页面 (虽然我不处理设置,所以我没有使用PreferenceActivity)我有这个function工作通过资源状态select器状态select器,除了点击列表视图菜单上的情况下,改变线性列表视图右侧的布局(分屏视图的sorting)。 我猜listview失去焦点,所以state_pressed不再是真实的。

<item android:state_pressed="true"> <shape > <solid android:color="@color/blue1" /> </shape> </item> 

任何提示,以保持该列表视图项目着色,直到另一个列表视图项目被选中? 谢谢!

编辑:

我能够通过setOnItemClickListener更改背景

 view.setBackgroundResource(R.color.red); 

我只需要一次select一个,所以当其他列表项被点击时,我尝试了lv.invalidate()lv.getChildAt(0).invalidate()但都没有工作,第二个导致空指针exception。 任何想法把颜色回来?

Solutions Collecting From Web of "ListView项目不会保持“select”"

当你从单元格释放你的手指,它不再注册为按下。 当用户select的时候,你想要做的事实际上是改变个别行的背景。 这意味着实现一个onItemClick或onItemTouch并标记适配器重新绘制与新的背景的行。 如果您已经在使用自定义列表适配器,则可以在getView()方法中针对布尔值执行检查。 您还需要跟踪哪些行被选中,哪些不是。

伪代码:

  public View getView(int pos, View convertView, ViewGroup parent) { if(isChecked[pos]) //set background to checked color } 

希望这个帮助,

1.-为关注的项目创build一个形状文件:\ drawable \ list_selector_focused.xml

  <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="90" android:startColor="#f5c98c" android:endColor="#f7ddb8"/> </shape> 

2.-为按下的项目创build一个形状文件:\ drawable \ list_selector_pressed.xml

  <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="90" android:startColor="#fb9d23" android:endColor="#ffc579" /> </shape> 

3.-创build列表select器文件:\ drawable \ list_selector.xml

  <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" /> <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" /> <item android:drawable="@drawable/list_selector_focused" /> </selector> 

4.-将该属性添加到布局文件中的ListView中:

  android:choiceMode="singleChoice" android:listSelector="@drawable/list_selector" 

您可以使用颜色代替渐变形状,

这是斯特曼的想法的实现:

  package com.mypackage; import java.util.Vector; import com.myapp.R; import com.myapp.data.Address; import android.content.Context; import android.graphics.Color; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class AddressesListAdapter extends BaseAdapter{ protected Context context; protected LayoutInflater mInflater; protected int itemResourceId; protected Vector<Address> contentItems = new Vector<Address>(); protected Vector<Boolean> selectedStates; private static final String TAG = "myapp"; public AddressesListAdapter(Context context, Vector<Address> contentItems) { this.context = context; this.contentItems = contentItems; mInflater = LayoutInflater.from(context); itemResourceId = R.layout.address_list_item; selectedStates = new Vector<Boolean>(); //initial fill clearSelectedState(); } @Override public int getCount() { return contentItems.size(); } @Override public Object getItem(int position) { return contentItems.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(itemResourceId, null); holder = new ViewHolder(); holder.addressName = (TextView) convertView.findViewById(R.id.addressName); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Address address = (Address) contentItems.get(position); holder.addressName.setText(address.getAddressName()); holder.addressName.setOnClickListener(new SetFocusListener(position)); //restore saved position from saving vector if (selectedStates.get(position)) holder.addressName.setBackgroundColor(Color.BLUE); else holder.addressName.setBackgroundColor(Color.TRANSPARENT); return convertView; } private void clearSelectedState () { selectedStates.clear(); for (int i = 0 ; i <= contentItems.size(); i++) { selectedStates.add(new Boolean(false)); } } private class SetFocusListener implements View.OnClickListener { private int position; public SetFocusListener(int position) { this.position = position; } @Override public void onClick(View v) { //clear selected state vector clearSelectedState(); //set selected position selectedStates.set(position, new Boolean(true)); //refresh adapter to redraw focus notifyDataSetChanged(); } } static class ViewHolder { TextView addressName; } } 

只关心为每个getView()迭代设置新的监听器代价高昂

检查的android状态最好用来解决这个问题。

有人提到使用android:background =“?android:attr / activatedBackgroundIndicator”。

这只是指向Android源代码的frameworks / base / core / res / res / drawable中的一个activated_background_ *资源。 例如activated_background_holo_dark.xml:

 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" /> <item android:drawable="@color/transparent" /> </selector> 

所以基本上你想要使用state_activated来表示当用户按下button时,以及当它处于检查状态(即处于持续select状态)时。 请注意,只有在Honeycomb之后才会启用激活,如果您的目标是旧设备,则需要依赖state_checked(更多详细信息,请参阅此处 )。

现在,如果你想设置一个项目作为选中,你需要调用listView.setItemChecked(position, true) 。 您可能想要将ListView上的android:choiceMode属性设置为适当的值(例如,如果您只想在一次select一件事情时使用singleChoice )。 你不需要失效,对setItemChecked的调用将会触发一个更新视图的重新布局。

如果允许在ListView中重新sorting项目,请注意,因为当前选中的项目将需要更新。 如果你使用稳定的ID,这将被自动处理。

要查看这个实例的示例,请查看培训系列中的NavigationDrawer示例代码: http : //developer.android.com/training/implementing-navigation/nav-drawer.html 。

默认情况下,当你使用触摸界面时,“Selected”和“Clicked”不一样 – 当我开始Android开发时,会导致一些真正的麻烦。

要同时支持通过touch和使用滚轮/轨迹球的用户进行导航,您可能需要使用setSelection ,并在AdapterView.OnItemSelectedListener实现(使用setOnItemSelectedListener设置)中进行操作。

另一个问题是,如果最后一个事件是触摸事件, setSelection将不会突出显示一个项目。

我build议你为列表项目创build一个自定义视图,并在那里处理突出显示。

希望这可以帮助,

菲尔·莱罗

好的,所以我尝试了上面的解决scheme,它说:“这是sgarman想法的实现:”这只适用于如果SetFocusListener是一个OnTouchListner。 另外,onClick方法消耗点击。 我不得不将这个解决scheme与我的列表项目上的OnItemClick监听器配对,以获取列表来实际显示突出显示的项目。

我用android:state_activated="true"而不是state_selected 。 它就像一个魅力!

如果通过整个活动保持listView,则可以在getView()方法中执行mListView.isItemChecked(position) 。 而他们根据结果设置背景颜色。

你有没有尝试android:state_selected="true"

尝试

  android:background="?android:attr/activatedBackgroundIndicator" 

;)