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

本文介绍了一种解决Android ListView中某行背景色更改后出现的显示错误问题的方法。通过自定义Adapter并调整缓存视图的方式,确保背景色正确显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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(){
		@Override
		public void handleMessage(Message message) {
			@SuppressWarnings("unchecked")
			List<Map<String, String>> l = (List<Map<String, String>>) message.obj;
			data.addAll(l);
			adapter.notifyDataSetChanged();
		}
	};
	
	@Override
	protected 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() {
			@Override
			public 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;
		}
		
		@Override
		public 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;
		}
	}

	@Override
	public 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简单,这里几不贴代码了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值