如何解决ListView项不会保持“选定”状态
| 我想在用户单击列表视图项目时更改其背景。有点像“蜂窝设置”页面(尽管我不只处理设置,所以我不使用PreferenceActivity)我通过资源状态选择器状态选择器来实现此功能,除了单击列表视图菜单更改的情况外列表视图右侧的线性布局(一种分屏视图)。我猜想listview失去了焦点,所以state_pressed不再成立。 <item android:state_pressed=\"true\">
<shape >
<solid android:color=\"@color/blue1\" />
</shape>
</item>
有什么技巧可以使该listview项目保持彩色,直到选择另一个listview项目?谢谢!
编辑:
我能够使用setonItemClickListener更改背景
view.setBackgroundResource(R.color.red);
我一次只需要选择一个,所以当单击其他列表项时,我尝试了lv.invalidate()
和lv.getChildAt(0).invalidate()
,但都没有用,而第二个则导致空指针异常。有什么想法可以恢复色彩吗?
解决方法
当您从单元格中松开手指时,它不再显示为已按下状态。实际上,您要做的是在用户选择“是”时更改单个行的背景。这意味着实现onItemClick或onItemTouch并标记适配器以使用新背景重新绘制该行。如果您已经在使用自定义列表适配器,则可以在getView()方法中对布尔值进行检查。您还需要跟踪哪些行被“选中”,哪些行未被“选中”。
伪代码:
public View getView(int pos,View convertView,ViewGroup parent) {
if(isChecked[pos]) //set background to checked color
}
,希望有帮助
1.-为重点项目创建形状文件:\\ 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.-为按下的项目创建形状文件:\\ 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.-创建列表选择器文件:\\ 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\"
您可以使用颜色代替渐变形状,
,这是sgarman想法的实现:
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,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来表示用户在处于选中状态(即处于持久选定状态)时按下按钮的时间。请注意,激活仅在Honeycomb之后引入,如果您要定位较旧的设备,则需要依靠state_checked(更多详细信息在这里)。
现在,如果您想将某项设置为选中状态,则需要调用listView.setItemChecked(position,true)
。您可能需要将ListView的android:choiceMode
属性设置为适当的值(例如,如果一次只选择一项,则使用singleChoice
)。您不需要使之无效,对setItemChecked的调用将触发一个重新布局,该布局将更新视图。
另外,如果允许在ListView中对项目进行重新排序,请当心,因为当前选中的项目将需要更新。如果您使用稳定的ID,则会自动处理。
要查看实际操作的示例,请查看在培训系列中找到的NavigationDrawer示例代码:http://developer.android.com/training/implementing-navigation/nav-drawer.html。
,默认情况下,当您使用触摸屏时,“选择的”与“单击的”是不同的-在我开始Android开发时,这让我有些头疼。
为了同时支持通过触摸导航的用户和使用滚轮/轨迹球的用户,您可能需要使用setSelection,并在AdapterView.OnItemSelectedListener实现(通过setOnItemSelectedListener设置)中进行操作。
另一个陷阱是,如果最后一个事件是触摸事件,则setSelection不会突出显示项。
我建议您为列表项创建一个自定义视图,并在其中处理突出显示。
希望这可以帮助,
菲尔·莱洛
,好的,所以我尝试从上面的解决方案中说“这是sgarman想法的实现:”,这仅在SetFocusListener是OnTouchListner时才有效。否则,onClick方法会消耗点击。我必须将此解决方案与列表项上的OnItemClick侦听器配对,以使列表实际显示突出显示的项。
,我用的是android:state_activated=\"true\"
而不是state_selected
。它就像一个魅力!
,如果您在整个活动中保留listView,则可以在getView()
方法中执行mListView.isItemChecked(position)
。然后根据结果设置背景色。
,您尝试过android:state_selected=\"true\"
吗?
,尝试
android:background=\"?android:attr/activatedBackgroundIndicator\"
;)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。