史上最全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
- <ListView android:id="@id/android:list"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="150dip"
- android:divider="#00000000"
- android:dividerHeight="0dip"
- android:listSelector="@android:color/transparent"
- 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;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。