觸碰模式下的listview的選中項背景高亮

       我在工作中發現:觸碰模式下的listview項無法被選中,所謂選中,意思是點擊選中該項後,背景長期高亮。
      在模擬器上測試時,可以使用鼠標滑輪滾動選中,這會調用onItemSelected()方法,在這裏可以設置選中項高亮。
      在真機上,由於沒有滑輪,只能用手指點擊選中,但是點擊時,不會有選中後高亮的效果(注意:選中後高亮不是指點擊選中那一下高亮,而是點擊後長期高亮)。
      或許你會想到使用selector背景選擇器來設置:

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

悲劇的是:我無法使用selector實現我想要的那種選中後長期高亮的狀態
於是我只能在java代碼中尋求思路了

下面的代碼實現listview單選模式下點擊後背景圖片長期高亮
package org.yaoming.listview;

import org.yaoming.util.Common;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
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.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class Listview_selectorActivity extends Activity implements OnItemClickListener {
    private String[] arrays;
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        arrays = new String[] {"a","b","c","d","e"};
        //使用SharedPreferences是爲了每次點擊退出時都保存之前選中的項,以後一打開時就可以看到以前的選擇
        SharedPreferences sp = getSharedPreferences("testListview", 0);
        Common.SELECTED = sp.getInt("selected", Common.SELECTED);
        ListView listview =  (ListView) findViewById(R.id.listView1);
        listview.setAdapter(new MyAdapter(this));
        listview.setOnItemClickListener(this);
        
    }
    public class MyAdapter extends BaseAdapter{
    	Context context;
    	
    	public class ViewHolder{
    		TextView tv;
    		ImageView iv;
    	} 
    	
    	public MyAdapter(Context context){
    		this.context = context; 
    	}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return arrays.length;
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			//通過日誌測試,原來每次點擊listview的每一項,這裏都會運行
			//通過查看源碼,原來是getItemAtPosition()中getAdapter()搞的鬼
			Log.i("listview", "zhixingguo ");
			
			LinearLayout layout;
			ViewHolder viewholder;
			if(null == convertView){
				layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.item, null);
				viewholder = new ViewHolder();
			    viewholder.tv = (TextView) layout.findViewById(R.id.textView2);
				viewholder.iv = (ImageView) layout.findViewById(R.id.imageView1);
				convertView = layout;
				layout.setTag(viewholder);
			}else{
				layout = (LinearLayout) convertView;
				viewholder = (ViewHolder) layout.getTag();
			}
			
			viewholder.tv.setText(arrays[position]);
			//在這裏加個判斷,若爲選中項,則改變背景圖片和背景色
			if(Common.SELECTED == position){
				viewholder.iv.setBackgroundResource(R.drawable.asi);
				layout.setBackgroundResource(R.color.blue);
			}else {
				viewholder.iv.setBackgroundResource(R.drawable.icon);
				layout.setBackgroundResource(R.color.transparent);
			}
			return convertView;
		}
    	
    }
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		//如果在這裏簡單地通過findviewbyid()改變背景圖片,點擊時會出現圖片亂顯示的情況
//		ImageView iv =  (ImageView) view.findViewById(R.id.imageView1);
//		iv.setImageResource(R.drawable.asi);
		
		//改變SELECTED的值,並在getview裏判斷加載的位置是否爲選中的位置
		Common.SELECTED = position;
	}
	
}

還有一個自定義的util類
package org.yaoming.util;

public class Common {
   public static int SELECTED = -1;
}


另外,main.xml的代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:text="@string/hello" />
	<ListView android:id="@+id/listView1" android:choiceMode="singleChoice"
		android:cacheColorHint="#00000000" android:layout_height="wrap_content"
		android:layout_width="match_parent"></ListView>
</LinearLayout>

listview的item佈局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="match_parent"
	android:layout_height="match_parent">
	<TextView android:text="TextView"
		android:id="@+id/textView2" android:textSize="30sp"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"></TextView>
	<ImageView android:src="@drawable/icon"
		android:layout_width="wrap_content" android:id="@+id/imageView1"
		android:layout_height="wrap_content"></ImageView>

</LinearLayout>

不使用selector,直接在java代碼裏設置。在onItemClick的時候獲得position,並在getview判斷是否爲選中項,設置背景顏色高亮,記得佈局文件中listview要設置成singleChoiceMode。
值得注意的是,onItemClick會觸發getItemAtPosition方法
    /**
         * Callback method to be invoked when an item in this AdapterView has
         * been clicked.
         * <p>
         * Implementers can call getItemAtPosition(position) if they need
         * to access the data associated with the selected item.
         *
         * @param parent The AdapterView where the click happened.
         * @param view The view within the AdapterView that was clicked (this
         *            will be a view provided by the adapter)
         * @param position The position of the view in the adapter.
         * @param id The row id of the item that was clicked.
         */
        void onItemClick(AdapterView<?> parent, View view, int position, long id);
    }

getItemAtPosition又會調用getAdapter方法,就相當於重新刷新一次ui中的listview
/**
     * Gets the data associated with the specified position in the list.
     *
     * @param position Which data to get
     * @return The data associated with the specified position in the list
     */
    public Object getItemAtPosition(int position) {
        T adapter = getAdapter();
        return (adapter == null || position < 0) ? null : adapter.getItem(position);
    }

實現效果如下:


第一次寫技術博客,多有差池請多多指教,如有說不清楚的地方,請賜教。
下面是源碼下載地址
http://download.csdn.net/detail/iamkila/4034770



發佈了25 篇原創文章 · 獲贊 29 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章