当前位置:   article > 正文

史上最全selector和shape使用方法 Android ListView 列表项点击之后,保持背景颜色_安卓listview选中项时如何如何改变文字颜色不改背景

安卓listview选中项时如何如何改变文字颜色不改背景

     ==========================分割线2015年11月26日08:04:07============================= 

   下面的文章存在bug,实际上未能解决保持背景的问题,误导大家不好意思,根据朋友的帮忙,我更新了另一片博客解决此需求,如下链接:android 点击更换背景,已读功能,希望对大家有帮忙,有问题,可以相互讨论!!!大笑


  ==========================分割线2015年11月26日08:04:07============================= 

 项目中突然遇到这样的问题,一些消息类的界面,需要使用listview进行显示,正常的需求是刚开始进入消息显示界面的时候,列表项显示的都是全黑的,接着点击了某一个列表项之后,就要更换成白色,并且保持白色的显示,剩下的仍旧为黑色的,一开始就有点走进了死胡同,使用selector结合shape来定义选中、未选中、点击或者点击之后的背景显示,实例如下:

<?xml version="1.0" encoding="utf-8" ?>     
<selector xmlns:android="http://schemas.android.com/apk/res/android">   
<!-- 默认时的背景图片-->    
  <item android:drawable="@drawable/pic1" />      
<!-- 没有焦点时的背景图片 -->    
  <item android:state_window_focused="false"     
        android:drawable="@drawable/pic1" />     
<!-- 非触摸模式下获得焦点并单击时的背景图片 -->    
  <item android:state_focused="true" android:state_pressed="true"   android:drawable= "@drawable/pic2" />   
<!-- 触摸模式下单击时的背景图片-->    
<item android:state_focused="false" android:state_pressed="true"   android:drawable="@drawable/pic3" />    
<!--选中时的图片背景-->    
  <item android:state_selected="true"   android:drawable="@drawable/pic4" />     
<!--获得焦点时的图片背景-->    
  <item android:state_focused="true"   android:drawable="@drawable/pic5" />     
</selector>

上述的代码是由很多前辈提供的,的确是能实现点击之后改变颜色,但问题来了,点击之后松开手指,就会显示成默认的背景颜色,无法保持背景颜色,感谢csdn的那些前辈对于这个问题的分析,贴出如下:

1.selector写法是在item处于selected状态时变成灰色但是ListView默认点击item再松开就恢复到默认,并不是像TabWidget一样处于selected状态

2.listview item的点击,不是点击一次就变为选中状态的未被点击:初始状态点击:按下状态点击后松开:初始状态

这也就解释了,我现在无法通过selector来完成点击之后保持颜色,不过另一位高手提出了这样的解决方案

其实你在ListView的OnItemClickListener里边,将当前选中的item执行setSelected(true)就好了

按照他的方法,我在监听列表项点击函数写了如下代码:
  1. ListView listView = (ListView) getActivity().findViewById(
  2. R.id.listmessage);
  3. listView.setOnItemClickListener(new OnItemClickListener() {
  4. @Override
  5. public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
  6. long arg3) {
  7. AlertDialog.Builder builder = new AlertDialog.Builder(
  8. getActivity());
  9. builder.setIcon(R.drawable.ic_launcher);
  10. builder.setTitle(maps.get(arg2).get("messagetitle").toString());
  11. MessageToAccount metoacc = TradeAPI.getInstance().queryMessage(
  12. (String) maps.get(arg2).get("guid"));
  13. byte[] messagebyte = metoacc.getContext();
  14. if (messagebyte != null) {
  15. try {
  16. new String(messagebyte, "UTF-8");
  17. } catch (UnsupportedEncodingException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. // builder.setMessage(messagecontent);
  22. builder.setMessage("现货交易中通行的是一手交钱一手交货的交易方式,或者采取以货易货的交易方式。的方式在限期内结算。现货交易与其它交易方式的不同点有:①在交易的目的上,是为了获得商品的所有权。");
  23. builder.show();
  24. }
  25. });</span>

最最关键的莫过于这段代码:
   arg1.setSelected(true);就实现了每次点击之后保持颜色不变。至此效果完成了,贴出我的selector的xml文件:</span></span>
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector
  3. xmlns:android="http://schemas.android.com/apk/res/android">
  4. <item android:state_selected="true">
  5. <shape>
  6. <!-- 渐变 -->
  7. <gradient
  8. android:startColor="#B4B4B4"
  9. android:endColor="#B4B4B4"
  10. android:type="radial"
  11. android:gradientRadius="50" />
  12. <!-- 描边 -->
  13. <stroke
  14. android:width="2dp"
  15. android:color="#dcdcdc"
  16. android:dashWidth="5dp"
  17. android:dashGap="3dp" />
  18. <!-- 圆角 -->
  19. <corners
  20. android:topLeftRadius="5dp"
  21. android:topRightRadius="5dp"
  22. android:bottomLeftRadius="5dp"
  23. android:bottomRightRadius="5dp"/>
  24. <padding
  25. android:left="10dp"
  26. android:top="10dp"
  27. android:right="10dp"
  28. android:bottom="10dp" />
  29. </shape>
  30. </item>
  31. <item android:state_pressed="true">
  32. <shape>
  33. <!-- 渐变 -->
  34. <gradient
  35. android:startColor="#B4B4B4"
  36. android:endColor="#B4B4B4"
  37. android:type="radial"
  38. android:gradientRadius="50" />
  39. <!-- 描边 -->
  40. <stroke
  41. android:width="2dp"
  42. android:color="#dcdcdc"
  43. android:dashWidth="5dp"
  44. android:dashGap="3dp" />
  45. <!-- 圆角 -->
  46. <corners
  47. android:topLeftRadius="5dp"
  48. android:topRightRadius="5dp"
  49. android:bottomLeftRadius="5dp"
  50. android:bottomRightRadius="5dp"/>
  51. <padding
  52. android:left="10dp"
  53. android:top="10dp"
  54. android:right="10dp"
  55. android:bottom="10dp" />
  56. </shape>
  57. </item>
  58. <item>
  59. <shape>
  60. <solid android:color="#2B2B2B"/>
  61. <stroke
  62. android:width="2dp"
  63. android:color="#2B2B2B" />
  64. <corners
  65. android:topLeftRadius="5dp"
  66. android:topRightRadius="5dp"
  67. android:bottomLeftRadius="5dp"
  68. android:bottomRightRadius="5dp"
  69. />
  70. <padding
  71. android:left="10dp"
  72. android:top="10dp"
  73. android:right="10dp"
  74. android:bottom="10dp" />
  75. </shape>
  76. </item>
  77. </selector>
    
    这里虽然实现了保持颜色的效果,但是在点击按下列表项的时候,背景会有默认的黄色背景,找到了如下的解决方案:
     就是在listview标签里面设置选中时为透明的背景:<?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="match_parent"
    android:background="@color/background"
    android:orientation="vertical" >


    <ListView
        android:id="@+id/listmessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:listSelector="@android:color/transparent"  >
    </ListView>
    成功解决!!!

    还遇到一个问题,就是显示的时候有一个黑色的分割线,好难看,需要隐藏掉:
 

android listview去掉分割线

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ListView android:id="@id/android:list"  
  2.           android:layout_width="fill_parent"   
  3.           android:layout_height="wrap_content"  
  4.           android:layout_marginTop="150dip"  
  5.           android:divider="#00000000"  
  6.           android:dividerHeight="0dip"  
  7.           android:listSelector="@android:color/transparent"   
  8.           android:layout_gravity="center_vertical"/>  
   第四个需求就是:点击了某一个列表项之后,要求改变字体的颜色,这里的解决方案是:
     第一步:设定一个全局变量,保存哪个列表项被点击了。
    第二步:在列表项点击监听事件中,取得被点击的列表项的具体行数,传给适配器,如果和position匹配,则得到改textview,然后就可以进行判断,如果点击的行数和postion一样,则更改颜色,并进行列表更新。
   代码如下:
   
  1. package client.verbank.mtp.allone.frame.message;
  2. import java.io.UnsupportedEncodingException;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.LinkedList;
  6. import java.util.List;
  7. import jedi.verbank.CSTS3.comm.struct.MessageToAccount;
  8. import jedi.verbank.client.station.api.ClientAPI;
  9. import jedi.verbank.client.station.api.trade.TradeAPI;
  10. import jedi.verbank.client.station.api.trade.TradeResult_SimpleReport;
  11. import android.app.AlertDialog;
  12. import android.app.ProgressDialog;
  13. import android.content.Context;
  14. import android.os.Bundle;
  15. import android.os.Handler;
  16. import android.view.LayoutInflater;
  17. import android.view.View;
  18. import android.view.ViewGroup;
  19. import android.widget.AdapterView;
  20. import android.widget.AdapterView.OnItemClickListener;
  21. import android.widget.BaseAdapter;
  22. import android.widget.ListView;
  23. import android.widget.TextView;
  24. import client.verbank.mtp.allone.R;
  25. import client.verbank.mtp.allone.component.DialogManager;
  26. import client.verbank.mtp.allone.component.DialogType;
  27. import client.verbank.mtp.allone.consts.IBundleCommData;
  28. import client.verbank.mtp.allone.frame.ControlFragment;
  29. import client.verbank.mtp.allone.frame.MainActivity;
  30. import client.verbank.mtp.allone.util.TimeUtil;
  31. public class MessageFragment extends ControlFragment {
  32. private int selectItem = -1;
  33. /*
  34. * :对展示的listview列表项进行监听,主要使用fragment的onActivityCreated的Activity创建完成之后
  35. * 取到列表的值,进行更新。
  36. */
  37. @Override
  38. public void onActivityCreated(Bundle savedInstanceState) {
  39. super.onActivityCreated(savedInstanceState);
  40. ListView listView = (ListView) getActivity().findViewById(
  41. R.id.listmessage);
  42. listView.setOnItemClickListener(new OnItemClickListener() {
  43. @Override
  44. public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
  45. long arg3) {
  46. <span style="font-size:24px;color:#ff0000;"><strong>arg1.setSelected(true);
  47. selectItem = arg2; // 当前选择的节目item
  48. messageAd.notifyDataSetChanged(); // 通知adapter刷新数据 }</strong></span>
  49. AlertDialog.Builder builder = new AlertDialog.Builder(
  50. getActivity());
  51. builder.setIcon(R.drawable.ic_launcher);
  52. builder.setTitle(maps.get(arg2).get("messagetitle").toString());
  53. MessageToAccount metoacc = TradeAPI.getInstance().queryMessage(
  54. (String) maps.get(arg2).get("guid"));
  55. byte[] messagebyte = metoacc.getContext();
  56. if (messagebyte != null) {
  57. try {
  58. new String(messagebyte, "UTF-8");
  59. } catch (UnsupportedEncodingException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. // builder.setMessage(messagecontent);
  64. builder.setMessage("现货交易中通行的是一手交钱一手交货的交易方式,或者采取以货易货的交易方式。的方式在限期内结算。现货交易与其它交易方式的不同点有:①在交易的目的上,是为了获得商品的所有权。");
  65. builder.show();
  66. }
  67. });
  68. }
  69. // 开仓单适配器
  70. public class MessageAdapter extends BaseAdapter {
  71. public MessageAdapter(Context myContext) {
  72. }
  73. public MessageAdapter(MessageFragment messageFragment) {
  74. }
  75. @Override
  76. public int getCount() {
  77. if (maps == null) {
  78. return 0;
  79. }
  80. return maps.size();
  81. }
  82. @Override
  83. public Object getItem(int position) {
  84. return position;
  85. }
  86. @Override
  87. public long getItemId(int position) {
  88. return position;
  89. }
  90. @Override
  91. public View getView(int position, View convertView, ViewGroup parent) {
  92. ViewHolder viewHolder = null;
  93. if (convertView == null) {
  94. viewHolder = new ViewHolder();
  95. convertView = getActivity().getLayoutInflater().inflate(
  96. R.layout.activity_message_item, null);
  97. viewHolder.messagetitle = (TextView) convertView
  98. .findViewById(R.id.messagetitle);
  99. viewHolder.messagetime = (TextView) convertView
  100. .findViewById(R.id.messagetime);
  101. convertView.setTag(viewHolder);
  102. } else {
  103. viewHolder = (ViewHolder) convertView.getTag();
  104. }
  105. TextView messagetitle = (TextView) convertView
  106. .findViewById(R.id.messagetitle);
  107. TextView messagetime = (TextView) convertView
  108. .findViewById(R.id.messagetime);
  109. <span style="font-size:18px;color:#cc0000;"><strong> try {
  110. if (selectItem == position) {
  111. messagetitle.setTextColor(android.graphics.Color.BLACK);
  112. messagetime.setTextColor(android.graphics.Color.BLACK);
  113. viewHolder.messagetitle.setText(maps.get(position)
  114. .get("messagetitle").toString());
  115. viewHolder.messagetime.setText(maps.get(position)
  116. .get("messagetime").toString());
  117. } else {
  118. messagetitle.setTextColor(android.graphics.Color.WHITE);
  119. messagetime.setTextColor(android.graphics.Color.WHITE);
  120. viewHolder.messagetitle.setText(maps.get(position)
  121. .get("messagetitle").toString());
  122. viewHolder.messagetime.setText(maps.get(position)
  123. .get("messagetime").toString());
  124. }
  125. } catch (Exception ex) {
  126. ex.printStackTrace();
  127. }</strong></span>
  128. return convertView;
  129. }
  130. private class ViewHolder {
  131. TextView messagetitle;
  132. TextView messagetime;
  133. }
  134. }
  135. @Override
  136. public String getFragmentTitle() {
  137. return "";
  138. }
  139. @Override
  140. public int getFramentKey() {
  141. return IBundleCommData.FRAGMENT_ID_Message;
  142. }
  143. @Override
  144. public void onMessageReceive(MessageToAccount arg0) {
  145. if (!isHidden()) {
  146. initData();
  147. }
  148. }
  149. }
       这里的确可以通过上述方法对列表项的文字的颜色进行更改,但这又引起了其他的bug,就是列表项的背景之前是设置了selector和shape的,点击之后更换为白色的背景,但是按照上述的方法设置之后,全部为黑的,其实解决方案也简单,单独对点击和默认的布局,进行背景的设置,放弃掉之前的利用selector进行背景的改变,直接使用shape来设置,代码如下:
  
  1. try {
  2. if (selectItem == position) {
  3. messagetitle.setTextColor(android.graphics.Color.BLACK);
  4. messagetime.setTextColor(android.graphics.Color.BLACK);
  5. viewHolder.messagetitle.setText(maps.get(position)
  6. .get("messagetitle").toString());
  7. viewHolder.messagetime.setText(maps.get(position)
  8. .get("messagetime").toString());
  9. convertView.findViewById(R.id.expandable1)
  10. .setBackgroundColor(android.graphics.Color.WHITE);
  11. convertView.findViewById(R.id.expandable1)
  12. .setBackgroundResource(R.drawable.menu_shapeclick);
  13. } else {
  14. messagetitle.setTextColor(android.graphics.Color.WHITE);
  15. messagetime.setTextColor(android.graphics.Color.WHITE);
  16. viewHolder.messagetitle.setText(maps.get(position)
  17. .get("messagetitle").toString());
  18. viewHolder.messagetime.setText(maps.get(position)
  19. .get("messagetime").toString());
  20. convertView.findViewById(R.id.expandable1)
  21. .setBackgroundResource(
  22. R.drawable.menu_shapeunonclick);
  23. }
  24. } catch (Exception ex) {
  25. ex.printStackTrace();
  26. }
  27. return convertView;
  28. }

   ————————————————————————————分割线,textview 点击变换背景——————————————————
android:background="@drawable/systemsettingsseletor"
  android:clickable="true"
     android:focusable="true"
       android:focusableInTouchMode="true"

2.selector文件:<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">


    <item android:drawable="@drawable/grayright" android:state_focused="true"/>
    <item android:drawable="@drawable/grayright" android:state_pressed="true"/>


    <item android:drawable="@drawable/grayrightmoren"/>


</selector>


 
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号