ListView中想让text变色是一个比较棘手的问题,事实上有很多人都遇到了问题,可是能解决的方案不多,这个帖子旨在帮助大家
解决这个问题,好,让我们通过两种方式来看看。
1.用selector和setTextColor的方式
这是一种执行效率比较高的方法
一,在listview的adapter xml中找到要变色的控件,用setTextColor或者style来改变颜色,如下所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingLeft="5dip" android:descendantFocusability="blocksDescendants" android:background="@drawable/listview_state_bg" android:paddingRight="5dip"> <ImageButton android:id="@+id/headphoto" android:layout_width="45dip" android:layout_height="45dip" android:layout_marginTop="10dip" android:layout_marginLeft="10dip" android:focusable="false" android:background="@drawable/recfriend_pic_box" android:scaleType="fitCenter" android:src="@drawable/pic_bg" android:layout_marginBottom="10dip"/> <LinearLayout android:layout_width="fill_parent" android:id="@+id/text_layout" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="10dip" android:paddingTop="8dip" android:focusable="false" android:layout_weight="1"> <LinearLayout android:orientation="horizontal" android:focusable="false" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16dip" style="@style/textview_title" android:focusable="false"/> <ImageView android:id="@+id/pageicon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/page_icon_new" android:focusable="false" android:visibility="gone"/> <LinearLayout android:layout_width="wrap_content" android:focusable="false" android:layout_height="wrap_content" android:layout_weight="1"/> </LinearLayout> <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_marginTop="4dip" android:focusable="false" android:layout_height="wrap_content" android:textColor="@drawable/rec_button_color" android:textSize="14sp" android:visibility="gone"/> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:focusable="false" android:layout_height="wrap_content" android:textColor="@drawable/rec_button_color" android:textSize="14sp" android:visibility="gone"/> </LinearLayout> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="5dip" android:focusable="false" android:button="@drawable/checkbox" android:layout_gravity="center_vertical"/> <ImageButton android:id="@+id/arrow" android:layout_width="wrap_content" android:focusable="false" android:layout_height="wrap_content" android:background="@drawable/profile_icon_arrow" android:layout_gravity="center_vertical" android:layout_marginRight="5dip" android:visibility="gone"/> </LinearLayout>
特别注意的是,在你的adapter的最外层linearLayout里有一句话
android:descendantFocusability="blocksDescendants"
是必须的,否则无法实现点击变色,它的功能是覆盖子控件的onclick事件。解释如下:
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.
Must be one of the following constant values.
Constant | Value | Description |
---|---|---|
beforeDescendants |
0 | The ViewGroup will get focus before any of its descendants. |
afterDescendants |
1 | The ViewGroup will get focus only if none of its descendants want it. |
blocksDescendants |
2 | The ViewGroup will block its descendants from receiving focus. |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="false" android:color="@color/profile_color"/> <item android:state_pressed="true" android:color="@color/white"/> </selector>
style(注意不是android:style)指向的textview_title写在values/style.xml中,如下:
<?xml version= "1.0" encoding= "utf-8"?> <resources xmlns:adnroid="http://schemas.android.com/apk/res/android"> <style name="textview_title"> <item name="android:textColor">@color/title_color</item> <item name="android:duplicateParentState">true</item> </style> </resources>
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="@color/white" /> <item android:color="@color/black" /> </selector>
有时候我们的listeview item需要有点击事件,如在ListView Adapter类里的getView()中实现如下功能:
view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(holder.checkbox.isChecked()){ holder.checkbox.setChecked(false); }else { holder.checkbox.setChecked(true); } } } });
到子控件的点击变色部分。
所以需要有变通的方案,即在包含Listview的Activity中给Listview加入setOnItemClickListener,而不通过view.setOnClickListener:
mListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { RecommendFriendsAdapter.ViewHolder holder = (RecommendFriendsAdapter.ViewHolder)view.getTag(); if(holder.checkbox!= null){ if(holder.checkbox.isChecked()){ holder.checkbox.setChecked(false); }else { holder.checkbox.setChecked(true); } } } });这样即实现了点击变色,也实现了点击需要的其它功能。
如果需要在点击父控件时还要让checkbox变色,则在最上部分的checkbox一项里加入
android:button="@drawable/checkbox"其中checkbox.xml为:
<?xml version= "1.0" encoding= "UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/btn_checkbox_normal" android:state_checked="false" android:state_pressed="false"/> <item android:drawable="@drawable/btn_checkbox_pressed" android:state_checked="false" android:state_pressed="true"/> <item android:drawable="@drawable/bth_checkbox_normal" android:state_checked="true" android:state_pressed="false"/> <item android:drawable="@drawable/bth_checkbox_pressed" android:state_checked="true" android:state_pressed="true"/> </selector>这样就实现了选中变色。
累死lz了,这个方案前前后后搞了至少半个月,因为后面的setOnClickListener问题一直阻塞,现在终于搞出来了!
希望对自己和大家都有帮助。
2. 下面的方法是之前没有找到上面方法的替代方法,用于一些极端情况下能实现效果,
它的缺点是在滑动的时候也会有时触发点击效果,从而使得滑动变得比较卡,不过作为临时方法也可以接受,
同等情况优先使用第一种方法。
在adapter的getView()方法里加入下面的话
view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub Log.d("meng", "action + "+event.getAction()); if(event.getAction() == 0){ view.setBackgroundColor(Color.parseColor("#2cb1e1")); holder.name.setTextColor(Color.WHITE); holder.text1.setTextColor(Color.WHITE); holder.text2.setTextColor(Color.WHITE); }else if(event.getAction() == 2){ view.setBackgroundColor(Color.parseColor("#2cb1e1")); holder.name.setTextColor(Color.WHITE); holder.text1.setTextColor(Color.WHITE); holder.text2.setTextColor(Color.WHITE); }else if(event.getAction() == 3){ view.setBackgroundColor(Color.TRANSPARENT); holder.name.setTextColor(Color.BLACK); holder.text1.setTextColor(R.color.profile_color); holder.text2.setTextColor(R.color.profile_color); }else if(event.getAction() == 1){ view.setBackgroundColor(Color.TRANSPARENT); holder.name.setTextColor(Color.BLACK); holder.text1.setTextColor(R.color.profile_color); holder.text2.setTextColor(R.color.profile_color); }else{ Log.d("meng", "else + "+event.getAction()); view.setBackgroundColor(Color.TRANSPARENT); holder.name.setTextColor(Color.BLACK); holder.text1.setTextColor(R.color.profile_color); holder.text2.setTextColor(R.color.profile_color); } return false; }
注意:如果要同时换背景,最好用color值,用图片会产生布局混乱的问题,而且必须用
view.setBackgroundColor(Color.parseColor("#2cb1e1"));
不要用你自己定义的id R.color.xxx,这样颜色会变的,而且不能用
view.setBackgroundResource(R.color.item_click_color);
因为个别手机尤其是4.0系统的手机会出现点击一会就不变色的bug!
else其实可有可无了,是为了保险加入的。
参考链接http://gundumw100.iteye.com/blog/1169065
ps:今天发现有网站转了我的文章,但不标明作者,甚至都不写转,希望大家转载的时候
至少写上个转自mengweiqi33,谢谢!