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.
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. |
其中的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>
有时候我们的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);
}
}
}
});
即实现点击item实现其中的checkbox选中,如果加入这段代码,则点击变色不能成功,因为我们的外部view把内部控件的点击事件都覆盖了,不会执行
到子控件的点击变色部分。
所以需要有变通的方案,即在包含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,谢谢!