Android ListView选中列表项修改背景色

来源:互联网 发布:拍照答题软件 编辑:程序博客网 时间:2024/05/29 19:01

Android ListView选中某一行修改其背景色时,在原生的ListView类中有一个listSelector属性可实现此效果,不过发现有BUG。开始以为是Android版本太低(Android 2.3 其中有BUG)所以换成高版本(4.3) 做了个测试。发现BUG依然存在。估计是Android系统在ListView中一直存在的BUG。

需求:

        当点击某一行(第三行)时,第三行背景色变为绿色,当点击事件完成以后就一直保持为绿色的状态。只有当点击了其他行(第10行)的时候第三行的颜色才恢复为原来的颜色(白色),然后第十行的颜色修改为绿色

BUG描述如下:

        假设当选中列表项第二行的时候,第二行背景色修改为绿色。然后快速(注:一定非常快且ListView的列表项比较多才会出现此BUG)向下滑动ListView,此时会在比如在第60行背景色变为绿色(且不一定总是在第60行)。

 

经过几天的研究终于修复此问题,代码如下:

TestActivity.java

public class TestActitvty extends Activity implements OnItemClickListener{  ListView listview;ArrayAdapter<Map<String, String>> adapter;List<Map<String, String>> data = new ArrayList<Map<String, String>>();private View selectedView;private Integer index;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message message) {@SuppressWarnings("unchecked")List<Map<String, String>> l = (List<Map<String, String>>) message.obj;data.addAll(l);adapter.notifyDataSetChanged();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);listview = (ListView) findViewById(R.id.listview);adapter = new MyArrayAdapter(this, R.layout.activity_test_item, data);listview.setAdapter(adapter);listview.setOnItemClickListener(this);handler.post(new Runnable() {@Overridepublic void run() {Message m = new Message();m.what = 5;List<Map<String, String>> l = new ArrayList<Map<String,String>>();for(int i=0; i<100; i++){Map<String, String> map = new HashMap<String, String>();map.put("name", "name_"+i);l.add(map);}m.obj = l;handler.dispatchMessage(m);}});}private class MyArrayAdapter extends ArrayAdapter<Map<String, String>> {private List<Map<String, String>> list;public MyArrayAdapter(Context context, int resource, List<Map<String, String>> list) {super(context, resource, list);this.list = list;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Holder holder = null;if(convertView == null){holder = new Holder();convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_test_item, null);holder.name = (TextView)convertView.findViewById(R.id.item);convertView.setTag(holder);}else{holder = (Holder) convertView.getTag();}Map<String, String> map = this.list.get(position);holder.name.setText(map.get("name").toString());Resources resources = getResources();//判断当前重画行与被选中行是否是同一行//如是则修改当前重画的行背景为绿色//如不是则为默认白色if(index!=null && position==index){convertView.setBackgroundColor(resources.getColor(R.color.txt_green));//注:此行不能少,否则会有新的BUG(本人开始的时候就是在此处没重新在此做缓存,导致新的BUG出现。结果纠结了几天。)//具体是什么BUG自己研究吧selectedView = convertView;}else{convertView.setBackgroundColor(resources.getColor(R.color.txt_white));}return convertView;}class Holder {TextView name;}}@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {Resources resources = getResources();//修改当前选中行背景色为绿色view.setBackgroundColor(resources.getColor(R.color.txt_green));if(this.selectedView!=null && this.index!=position){//修改原被选中行为白色selectedView.setBackgroundColor(resources.getColor(R.color.txt_white));}//修改被选中行的缓存数据this.selectedView = view;this.index = position;}}

布局文件

activity_test_item.xml

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/item"    android:padding="10dp"    android:layout_width="fill_parent"    android:layout_height="wrap_content"></TextView>

activity_test.xml

<?xml version="1.0" encoding="utf-8"?><ListView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/listview"    android:layout_width="fill_parent"    android:layout_height="fill_parent"/>

其他string.xml简单,这里几不贴代码了

0 0