Android ListView行高亮显示
我是在谷歌搜索了整个网络后才发布这个问题的,没有找到解决我问题的有效方法。我知道其他几篇文章也讨论过这个问题,但没有一篇文章帮我解决了这个问题 我已经实现了一个ListView,其中选中的项目高亮显示。一切都很好,当我选择一行时,它会高亮显示,并且在使用myListView.setSelection(索引)时会高亮显示,但我有一个问题需要解决:当我单击布局中的任何其他视图(按钮、复选框、radiobutton ecc)时,ListView会丢失选择 以下是listview的实现方式: 我已经扩展了标准列表视图Android ListView行高亮显示,android,android-listview,listviewitem,android-custom-view,android-selector,Android,Android Listview,Listviewitem,Android Custom View,Android Selector,我是在谷歌搜索了整个网络后才发布这个问题的,没有找到解决我问题的有效方法。我知道其他几篇文章也讨论过这个问题,但没有一篇文章帮我解决了这个问题 我已经实现了一个ListView,其中选中的项目高亮显示。一切都很好,当我选择一行时,它会高亮显示,并且在使用myListView.setSelection(索引)时会高亮显示,但我有一个问题需要解决:当我单击布局中的任何其他视图(按钮、复选框、radiobutton ecc)时,ListView会丢失选择 以下是listview的实现方式: 我已经扩展
public SelectableListView(Context context) {
super(context);
initStyle(null);
}
public SelectableListView(Context context, AttributeSet attrs) {
super(context, attrs);
initStyle(attrs);
}
public SelectableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initStyle(attrs);
}
private void initStyle(AttributeSet attrs) {
this.setBackgroundResource(R.drawable.red_border_fat);
this.setPadding(3, 3, 3, 3);
this.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
//without the following 2 lines the selection won't work
requestFocusFromTouch();//
arg1.setSelected(true);
}
});
}
@Override
public void setSelection(int position) {
//without the following line the selection won't work
requestFocusFromTouch();
super.setSelection(position);
}
public SelectableListView(上下文){
超级(上下文);
initStyle(null);
}
公共可选择列表视图(上下文、属性集属性){
超级(上下文,attrs);
initStyle(attrs);
}
公共可选择列表视图(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
initStyle(attrs);
}
私有void initStyle(AttributeSet attrs){
这个.setBackgroundResource(R.drawable.red\u border\u fat);
这个。设置填充(3,3,3,3);
this.setOnItemClickListener(新的OnItemClickListener(){
@凌驾
公共视图单击(AdapterView arg0、视图arg1、整型arg2、长型arg3){
//如果没有以下两行,选择将不起作用
requestFocusFromTouch()//
arg1.setSelected(true);
}
});
}
@凌驾
公共选举(内部职位){
//如果没有以下行,选择将不起作用
requestFocusFromTouch();
超级选举(职位);
}
listview以非常简单的方式添加到布局中
<my.name.space.SelectableListView
android:layout_width="wrap_content"
android:layout_height="100dp" >
</my.name.space.SelectableListView>
这是适配器
public static SimpleAdapter GetClassAdapter(Context context,ArrayList<SeatClass> items){
try {
final ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
String[] fields = new String[] { "className" };
int[] views = new int[] { R.skin_class.lblClassDescription};
SimpleAdapter adapter = new SimpleAdapter(context, list, R.layout.skin_class_list, fields, views);
for (SeatClass sc : items) {
HashMap<String, String> temp = new HashMap<String, String>();
temp.put("className", Typologic.getClasse(sc.Id).Description);
list.add(temp);
}
return adapter;
} catch (Exception e) {
LogHelper.WriteLogError("error in GetClassAdapter", e);
return null;
}
}
公共静态SimpleAdapter GetClassAdapter(上下文、ArrayList项){
试一试{
最终ArrayList=新ArrayList();
字符串[]字段=新字符串[]{“className”};
int[]views=newint[]{R.skin_class.lblclasssdescription};
SimpleAdapter=新SimpleAdapter(上下文、列表、R.layout.skin\u class\u列表、字段、视图);
用于(SeatClass sc:项目){
HashMap temp=新的HashMap();
temp.put(“className”,类型学.getClasse(sc.Id).Description);
列表。添加(临时);
}
返回适配器;
}捕获(例外e){
LogHelper.WriteLogError(“GetClassAdapter中的错误”,e);
返回null;
}
}
这是每行的布局(R.layout.skin\u class\u列表)
可选的\u listview\u background\u selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_focused="true" android:drawable="@color/black" />
<item android:state_selected="true" android:state_focused="false" android:drawable="@color/black" />
<item android:state_pressed="true" android:state_focused="true" android:drawable="@color/black" />
<item android:state_pressed="true" android:state_focused="false" android:drawable="@color/black" />
<item android:drawable="@color/White" />
</selector>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="@color/White" />:
<item android:state_pressed="true" android:color="@color/White" />:
<item android:color="@color/black" />
</selector>
可选的\u列表视图\u文本颜色\u选择器.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_focused="true" android:drawable="@color/black" />
<item android:state_selected="true" android:state_focused="false" android:drawable="@color/black" />
<item android:state_pressed="true" android:state_focused="true" android:drawable="@color/black" />
<item android:state_pressed="true" android:state_focused="false" android:drawable="@color/black" />
<item android:drawable="@color/White" />
</selector>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="@color/White" />:
<item android:state_pressed="true" android:color="@color/White" />:
<item android:color="@color/black" />
</selector>
:
:
正如我所说的,这非常有效,但是当我点击任何其他视图时,我无法保持高亮显示。我已经找了好几天的解决办法,但似乎什么都不管用
编辑:
我找到了这个解决方案,我不再使用选择器了。在这里,MyLabel是一个自定义文本视图,具有一些与本例无关的特性
public abstract class SelectableListView<T> extends ListView {
protected ArrayList<T> _data;
protected int _selectedIndex = 0;
public SelectableListView(Context context) {
super(context);
initStyle(null);
}
public SelectableListView(Context context, AttributeSet attrs) {
super(context, attrs);
initStyle(attrs);
}
public SelectableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initStyle(attrs);
}
public abstract void loadData(ArrayList<T> data);
public T getSelectedItem() {
if (_selectedIndex < 0)
return null;
else
return _data.get(_selectedIndex);
}
public T getItemAt(int position) {
if (position < 0 || position > _data.size())
return null;
else
return _data.get(position);
}
@Override
public void setSelection(int position) {
colorizeSelection(position);
super.setSelection(position);
_selectedIndex = position;
}
private void colorizeSelection(int index){
try {
for (int i = 0; i < this.getCount(); i++) {
if(i==index)
this.getChildAt(i).setBackgroundColor(getResources().getColor(R.color.Red));
else
this.getChildAt(i).setBackgroundColor(getResources().getColor(R.color.White));
ViewGroup root=(ViewGroup) this.getChildAt(i);
colorizeSelection(root,i==index);
}
} catch (Exception e) {
LogHelper.WriteLogError("error in colorizeSelection function", e);
}
}
//this function is called recursively to scan all childs of a given view
private void colorizeSelection(ViewGroup v,boolean selected){
for (int j = 0; j < v.getChildCount(); j++) {
if(v.getChildAt(j) instanceof ViewGroup)
colorizeSelection((ViewGroup)v.getChildAt(j),selected);
else if (v.getChildAt(j) instanceof MyLabel) {
if(selected)
((MyLabel)v.getChildAt(j)).setTextColor(getResources().getColor(R.color.White));
else
((MyLabel)v.getChildAt(j)).setTextColor(getResources().getColor(R.color.black));
((NtvLabel)v.getChildAt(j)).invalidate();
}
}
}
private void initStyle(AttributeSet attrs) {
_selectedIndex = -1;
this.setBackgroundResource(R.drawable.red_border_fat);
this.setPadding(3, 3, 3, 3);
this.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
colorizeSelection(arg2);
_selectedIndex = arg2;
}
});
}
}
公共抽象类SelectableListView扩展了ListView{
受保护的ArrayList_数据;
受保护的整数_selectedIndex=0;
公共可选择列表视图(上下文){
超级(上下文);
initStyle(null);
}
公共可选择列表视图(上下文、属性集属性){
超级(上下文,attrs);
initStyle(attrs);
}
公共可选择列表视图(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
initStyle(attrs);
}
公共抽象void loadData(ArrayList数据);
公共T getSelectedItem(){
如果(_selectedIndex<0)
返回null;
其他的
返回_data.get(_selectedIndex);
}
公共T getItemAt(内部位置){
如果(位置<0 | |位置>_data.size())
返回null;
其他的
返回_data.get(位置);
}
@凌驾
公共选举(内部职位){
颜色选择(位置);
超级选举(职位);
_selectedIndex=位置;
}
私有void colorizeSelection(整数索引){
试一试{
for(int i=0;i