关于点击ListView使其中的子控件的text文字变色的问题

来源:互联网 发布:乐乎青年公寓吧 编辑:程序博客网 时间:2024/06/07 06:55

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事件。解释如下:

android:descendantFocusability

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.

ConstantValueDescriptionbeforeDescendants0The ViewGroup will get focus before any of its descendants.afterDescendants1The ViewGroup will get focus only if none of its descendants want it.blocksDescendants2The ViewGroup will block its descendants from receiving focus.


其中的ID name,text1,text2都是需要点击变色的textview,分别用了style和textColor,其中rec_button_color.xml如下:

<?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>

注意要写在drawable文件夹下。

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>

其中的@color/title_color是写在res/color文件夹下的一个xml,与rec_button_color.xml相似:

<?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>


二,至此xml文件的设置就结束了,正常情况下就可以实现点击变色了,可问题往往在这里出现了,

有时候我们的listeview item需要有点击事件,如在ListView Adapter类里的getView()中实现如下功能:

view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if(holder.checkbox.isChecked()){holder.checkbox.setChecked(false);}else {holder.checkbox.setChecked(true);} } }});

即实现点击item实现其中的checkbox选中,如果加入这段代码,则点击变色不能成功,因为我们的外部view把内部控件的点击事件都覆盖了,不会执行

到子控件的点击变色部分。

所以需要有变通的方案,即在包含Listview的Activity中给Listview加入setOnItemClickListener,而不通过view.setOnClickListener:

mListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubLog.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,谢谢!