史上最全selector和shape使用方法 Android ListView 清單項目點擊之後,保持背景顏色,selectorandroid

來源:互聯網
上載者:User

史上最全selector和shape使用方法 Android ListView 清單項目點擊之後,保持背景顏色,selectorandroid

       項目中突然遇到這樣的問題,一些訊息類的介面,需要使用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)就好了
按照他的方法,我在監聽清單項目點擊函數寫了如下代碼:
ListView listView = (ListView) getActivity().findViewById(R.id.listmessage);listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());builder.setIcon(R.drawable.ic_launcher);builder.setTitle(maps.get(arg2).get("messagetitle").toString());MessageToAccount metoacc = TradeAPI.getInstance().queryMessage((String) maps.get(arg2).get("guid"));byte[] messagebyte = metoacc.getContext();if (messagebyte != null) {try {new String(messagebyte, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}}// builder.setMessage(messagecontent);builder.setMessage("現貨交易中通行的是一手交錢一手交貨的交易方式,或者採取以貨易貨的交易方式。的方式在限期內結算。現貨交易與其它交易方式的不同點有:①在交易的目的上,是為了獲得商品的所有權。");builder.show();}});</span>

最最關鍵的莫過於這段代碼:
   arg1.setSelected(true);就實現了每次點擊之後保持顏色不變。至此效果完成了,貼出我的selector的xml檔案:</span></span>
<?xml version="1.0" encoding="utf-8"?>  <selector      xmlns:android="http://schemas.android.com/apk/res/android">      <item android:state_selected="true">          <shape>              <!-- 漸層 -->              <gradient                  android:startColor="#B4B4B4"                  android:endColor="#B4B4B4"                  android:type="radial"                  android:gradientRadius="50" />              <!-- 描邊 -->              <stroke                  android:width="2dp"                  android:color="#dcdcdc"                  android:dashWidth="5dp"                   android:dashGap="3dp" />              <!-- 圓角 -->              <corners                  android:topLeftRadius="5dp"                android:topRightRadius="5dp"                android:bottomLeftRadius="5dp"                 android:bottomRightRadius="5dp"/>              <padding                  android:left="10dp"                  android:top="10dp"                  android:right="10dp"                  android:bottom="10dp" />          </shape>      </item>        <item android:state_pressed="true">          <shape>              <!-- 漸層 -->              <gradient                  android:startColor="#B4B4B4"                  android:endColor="#B4B4B4"                  android:type="radial"                  android:gradientRadius="50" />              <!-- 描邊 -->              <stroke                  android:width="2dp"                  android:color="#dcdcdc"                  android:dashWidth="5dp"                   android:dashGap="3dp" />              <!-- 圓角 -->              <corners                  android:topLeftRadius="5dp"                android:topRightRadius="5dp"                android:bottomLeftRadius="5dp"                 android:bottomRightRadius="5dp"/>              <padding                  android:left="10dp"                  android:top="10dp"                  android:right="10dp"                  android:bottom="10dp" />          </shape>      </item>          <item>                 <shape>              <solid android:color="#2B2B2B"/>              <stroke                  android:width="2dp"                  android:color="#2B2B2B" />              <corners                   android:topLeftRadius="5dp"                android:topRightRadius="5dp"                android:bottomLeftRadius="5dp"                 android:bottomRightRadius="5dp"              />              <padding                  android:left="10dp"                  android:top="10dp"                  android:right="10dp"                  android:bottom="10dp" />          </shape>      </item>  </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 plaincopy
  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一樣,則更改顏色,並進行列表更新。   代碼如下:   
package client.verbank.mtp.allone.frame.message;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import jedi.verbank.CSTS3.comm.struct.MessageToAccount;import jedi.verbank.client.station.api.ClientAPI;import jedi.verbank.client.station.api.trade.TradeAPI;import jedi.verbank.client.station.api.trade.TradeResult_SimpleReport;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import client.verbank.mtp.allone.R;import client.verbank.mtp.allone.component.DialogManager;import client.verbank.mtp.allone.component.DialogType;import client.verbank.mtp.allone.consts.IBundleCommData;import client.verbank.mtp.allone.frame.ControlFragment;import client.verbank.mtp.allone.frame.MainActivity;import client.verbank.mtp.allone.util.TimeUtil;public class MessageFragment extends ControlFragment {private int selectItem = -1;/* * :對展示的listview清單項目進行監聽,主要使用fragment的onActivityCreated的Activity建立完成之後 * 取到列表的值,進行更新。 */@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);ListView listView = (ListView) getActivity().findViewById(R.id.listmessage);listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {<span style="font-size:24px;color:#ff0000;"><strong>arg1.setSelected(true);selectItem = arg2; // 當前選擇的節目itemmessageAd.notifyDataSetChanged(); // 通知adapter重新整理資料 }</strong></span>AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());builder.setIcon(R.drawable.ic_launcher);builder.setTitle(maps.get(arg2).get("messagetitle").toString());MessageToAccount metoacc = TradeAPI.getInstance().queryMessage((String) maps.get(arg2).get("guid"));byte[] messagebyte = metoacc.getContext();if (messagebyte != null) {try {new String(messagebyte, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}}// builder.setMessage(messagecontent);builder.setMessage("現貨交易中通行的是一手交錢一手交貨的交易方式,或者採取以貨易貨的交易方式。的方式在限期內結算。現貨交易與其它交易方式的不同點有:①在交易的目的上,是為了獲得商品的所有權。");builder.show();}});}// 開倉單適配器public class MessageAdapter extends BaseAdapter {public MessageAdapter(Context myContext) {}public MessageAdapter(MessageFragment messageFragment) {}@Overridepublic int getCount() {if (maps == null) {return 0;}return maps.size();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if (convertView == null) {viewHolder = new ViewHolder();convertView = getActivity().getLayoutInflater().inflate(R.layout.activity_message_item, null);viewHolder.messagetitle = (TextView) convertView.findViewById(R.id.messagetitle);viewHolder.messagetime = (TextView) convertView.findViewById(R.id.messagetime);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}TextView messagetitle = (TextView) convertView.findViewById(R.id.messagetitle);TextView messagetime = (TextView) convertView.findViewById(R.id.messagetime);<span style="font-size:18px;color:#cc0000;"><strong>try {if (selectItem == position) {messagetitle.setTextColor(android.graphics.Color.BLACK);messagetime.setTextColor(android.graphics.Color.BLACK);viewHolder.messagetitle.setText(maps.get(position).get("messagetitle").toString());viewHolder.messagetime.setText(maps.get(position).get("messagetime").toString());} else {messagetitle.setTextColor(android.graphics.Color.WHITE);messagetime.setTextColor(android.graphics.Color.WHITE);viewHolder.messagetitle.setText(maps.get(position).get("messagetitle").toString());viewHolder.messagetime.setText(maps.get(position).get("messagetime").toString());}} catch (Exception ex) {ex.printStackTrace();}</strong></span>return convertView;}private class ViewHolder {TextView messagetitle;TextView messagetime;}}@Overridepublic String getFragmentTitle() {return "公告資訊";}@Overridepublic int getFramentKey() {return IBundleCommData.FRAGMENT_ID_Message;}@Overridepublic void onMessageReceive(MessageToAccount arg0) {if (!isHidden()) {initData();}}}
       這裡的確可以通過上述方法對清單項目的文字的顏色變更,但這又引起了其他的bug,就是清單項目的背景之前是設定了selector和shape的,點擊之後更換為白色的背景,但是按照上述的方法設定之後,全部為黑的,其實解決方案也簡單,單獨對點擊和預設的布局,進行背景的設定,放棄掉之前的利用selector進行背景的改變,直接使用shape來設定,代碼如下:  
try {if (selectItem == position) {messagetitle.setTextColor(android.graphics.Color.BLACK);messagetime.setTextColor(android.graphics.Color.BLACK);viewHolder.messagetitle.setText(maps.get(position).get("messagetitle").toString());viewHolder.messagetime.setText(maps.get(position).get("messagetime").toString());convertView.findViewById(R.id.expandable1).setBackgroundColor(android.graphics.Color.WHITE);convertView.findViewById(R.id.expandable1).setBackgroundResource(R.drawable.menu_shapeclick);} else {messagetitle.setTextColor(android.graphics.Color.WHITE);messagetime.setTextColor(android.graphics.Color.WHITE);viewHolder.messagetitle.setText(maps.get(position).get("messagetitle").toString());viewHolder.messagetime.setText(maps.get(position).get("messagetime").toString());convertView.findViewById(R.id.expandable1).setBackgroundResource(R.drawable.menu_shapeunonclick);}} catch (Exception ex) {ex.printStackTrace();}return convertView;}




 

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.