当前位置:操作系统 > 安卓/Android >>

如何在触摸模式(Touch Mode)下高亮显示ListView选中行

这应该是大部分Android开发者在使用ListView时会碰到问题,在解决这个问题前,需要先了解什么叫触摸模式。
触摸模式(Touch Mode),在Android SDK的官方文档中有详细解释(http://developer.android.com/resources/articles/touch-mode.html),其大概内容如下:
• 用户通过触摸屏操作设备时,设备将自动进入触摸模式,相对的,使用键盘、轨迹球等其他设备时,设备处于非触摸模式
• 进入触摸模式后,View将失去焦点(Focus)和选择(Selection)状态(文本输入框是例外),原因是Android的设计者没有好的办法解决同时操作触摸屏和轨迹球、键盘等外部设备所带来的混乱状态
• Android的设计者认为进入触摸模式后,View失去焦点和选择状态不是一个需要修正的问题,开发者也不应该在触摸模式中试图保持View的焦点或选择状态,可以使用CheckBox或RadioButton等控件来标识选择状态
这种设计策略可以说完全是从工程师的思维而不是从用户的需求去考虑问题,新的手机的性能越来越强,屏幕分辨率越来越高,应用程序界面设计趋向复杂,使用触摸屏操作时居然连个高亮显示都无法做到,真是件十足坑爹的事。
考察了几种不同的实现后,评估其性能代价和解决方式的优雅程度,我决定用checked状态来模拟选择选择selection来实现ListView的选中行的高亮显示:
1. 将ListView设为CHOICE_MODE_SINGLE或CHOICE_MODE_MULTIPLE,使ListView支持checked/unchecked状态
2. 在ListView的适配器中,返回的View实现Checkable接口,跟随选中状态的改变而改变自身背景
下面是我的测试代码:
001 package org.noodies;
002   
003 import android.app.Activity;
004 import android.content.Context;
005 import android.graphics.drawable.Drawable;
006 import android.graphics.drawable.StateListDrawable;
007 import android.os.Bundle;
008 import android.view.View;
009 import android.view.ViewGroup;
010 import android.widget.BaseAdapter;
011 import android.widget.Checkable;
012 import android.widget.ListView;
013 import android.widget.TextView;
014   
015 public class TestListActivity extends Activity {
016   
017     private ListView mListView;
018   
019     @Override
020     public void onCreate(Bundle savedInstanceState) {
021         super.onCreate(savedInstanceState);
022         setContentView(R.layout.main);
023   
024         mListView = (ListView) findViewById(R.id.listView1);
025   
026         // 设为单选,允许列表项切换checked/unchecked状态
027         mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
028         // 列表的选择效果设为透明,由列表项自行维护各状态显示
029         mListView.setSelector(android.R.color.transparent);
030   
031         mListView.setAdapter(new TestAdapter());
032     }
033   
034     private class MyView extends TextView implements Checkable {
035   
036         private final int[] STATE_CHECKED = { android.R.attr.state_checked };
037   
038         private int[] mSavedState;
039         private boolean mChecked = false;
040   
041         public MyView(Context context) {
042             super(context);
043         }
044   
045         public void setChecked(boolean checked) {
046             if (mChecked != checked) {
047                 mChecked = checked;
048                 updateBackground();
049             }
050         }
051   
052         public boolean isChecked() {
053             return mChecked;
054         }
055   
056         public void toggle() {
057             setChecked(!mChecked);
058         }
059   
060         private void updateBackground() {
061             Drawable bg = this.getBackground();
062   
063             // 在这里切换checked/unchecked状态
064             if (bg.getClass().equals(StateListDrawable.class)) {
065                 if (isChecked()) {
066                     mSavedState = bg.getState();
067                     bg.setState(STATE_CHECKED);
068                 } else if (mSavedState != null) {
069                     bg.setState(mSavedState);
070                 }
071             }
072         }
073     }
074   
075     private class TestAdapter extends BaseAdapter {
076   
077         private String[] testData = { "test1", "test2", "abcd", "abcdefg" };
078   
079         public int getCount() {
080             return testData.length;
081         }
082   
083         public Object getItem(int position) {
084             return testData[position];
085         }
086   
087         public long getItemId(int position) {
088             return 0;
089         }
090   
091         public View getView(int position

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,