我在工作中发现:触碰模式下的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>
于是我只能在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://hi.csdn.net/attachment/201201/29/0_1327840722p7HZ.gif)
下面是源码下载地址
http://download.csdn.net/detail/iamkila/4034770
原文:http://blog.csdn.net/iamkila/article/details/7218351