我想在用户点击时更改listview项的背景。有点像Honeycomb settings page(虽然我没有处理只是设置所以我没有使用PreferenceActivity)我有这个功能通过资源状态选择器状态选择器工作,除了单击列表视图菜单更改的情况列表视图右侧的线性布局(一种分屏视图)。我猜测listview失去焦点所以state_pressed不再是真的。
<item android:state_pressed="true">
<shape >
<solid android:color="@color/blue1" />
</shape>
</item>
在选择另一个列表视图项目之前,是否保持列表视图项目的颜色有任何提示?谢谢!
修改
我能够使用
在setOnItemClickListener中更改背景view.setBackgroundResource(R.color.red);
我只需要一次选择一个,所以当点击其他列表项时,我尝试了lv.invalidate()
和lv.getChildAt(0).invalidate()
但是没有工作,第二个导致空指针异常。有什么想法让颜色回来?
答案 0 :(得分:9)
当您从手指中释放手指时,它不会再按下注册状态。您要做的实际上是在用户选择时更改单个行的背景。这意味着实现onItemClick或onItemTouch并标记适配器以使用新背景重绘行。如果您已经在使用自定义列表适配器,则可以在getView()方法中对布尔值实施检查。您还需要跟踪哪些行被“选中”,哪些不是。
伪代码:
public View getView(int pos, View convertView, ViewGroup parent) {
if(isChecked[pos]) //set background to checked color
}
答案 1 :(得分:5)
希望得到这个帮助,
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"
您可以使用颜色代替渐变形状
答案 2 :(得分:3)
这是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, 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()迭代设置新的侦听器可能代价高昂
答案 3 :(得分:3)
检查的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(更多详情here)。
现在,如果您要将项目设置为已选中,则需要致电listView.setItemChecked(position, true)
。您可能希望将ListView上的android:choiceMode
属性设置为适当的值(例如,如果您只想使用singleChoice
一次选择一项内容)。你不需要无效,对setItemChecked的调用将触发一个更新视图的重新布局。
如果允许重新排序ListView中的项目,则需要小心,因为当前检查的项目需要更新。如果使用稳定的ID,则会自动处理。
要查看此操作的示例,请查看培训系列中的NavigationDrawer示例代码:http://developer.android.com/training/implementing-navigation/nav-drawer.html。
答案 4 :(得分:2)
默认情况下,当您使用触控界面时,“已选择”与“点击”不同 - 当我开始Android开发时,这会让我感到非常头痛。
要支持通过触摸导航的用户和使用滚轮/轨迹球的用户,您可能需要使用setSelection,并在AdapterView.OnItemSelectedListener实施中进行操作(使用setOnItemSelectedListener设置)。
另一个问题是如果最后一个事件是触摸事件,setSelection将不会突出显示项目。
我建议您为列表项创建自定义视图,并在其中处理突出显示。
希望这有帮助,
Phil Lello
答案 5 :(得分:0)
好的,所以我尝试了上面提到的解决方案&#34;这是sgarman想法的实现:&#34;这仅在SetFocusListener是OnTouchListner时有效。然后onClick方法消耗了点击。我必须将此解决方案与我的列表项上的OnItemClick侦听器配对,以使列表实际显示突出显示的项目。
答案 6 :(得分:0)
我使用android:state_activated="true"
代替state_selected
。它就像一个魅力!
答案 7 :(得分:0)
如果您将listView保留在整个活动中,则可以在mListView.isItemChecked(position)
方法中执行getView()
。然后根据结果设置背景颜色。
答案 8 :(得分:-2)
您是否尝试过android:state_selected="true"
?
答案 9 :(得分:-2)
尝试
android:background="?android:attr/activatedBackgroundIndicator"
)