• android列表选择模式的实现


    我们或许曾一次又一次的接到这样的需求,有一堆数据需要用户去选择,并且以列表的方式呈现,根据需求,我们需要单选或者复选列表里面的数据,并且最终取得所选数据作下一步的操作。那么对于这个需求,我们聪明的程序员往往都能想到一些解决方案去处理。譬如我,咳咳,虽然我不是很聪明,但是我想到了。

    【也许这样实现是对的】通常需要选择的列表数据我都会在adapter所绑定的数据实体内增加一个标记代表是否选中,在点击的时候去遍历并改变adapter中的实体标记,通知更新,然后根据标记在adapter的getView方法改变视图样式。这样能直观地实现我们的需求。

    【探索更好的解决方案】上面那种方式,很直接,估计大家都能想到,但这样做存在一些问题,比如遍历的效率会低,比如我们的adapter会增加一些非功能性的代码,让我们的adapter变得复杂。但当我们更深入地了解listview之后,我们可以发现listview有个属性--choicemode,英文不错的童鞋都能翻译:选择模式。

    【选择模式的例子】这里我写了个简单的使用选择模式中单选的例子。其中关键的部分便是自定义view,也许这是这种方式唯一的弱点,必须使用自定义view.

    【自定义选项】自定义的列表项继承checkable,实现checkable内的方法修改列表项的界面状态。

     1 package com.change.selectablelistviewdemo;
     2 
     3 import android.content.Context;
     4 import android.widget.CheckBox;
     5 import android.widget.Checkable;
     6 import android.widget.LinearLayout;
     7 import android.widget.TextView;
     8 
     9 import com.change.selectablelistviewdemo.R;
    10 
    11 /**
    12  * 自定义选项view,实现checkable。在实现的方法中修改界面状态。
    13  * @author Change
    14  *
    15  */
    16 public class SelectItemView extends LinearLayout implements Checkable {
    17     CheckBox cbx;
    18     TextView name;
    19     public SelectItemView(Context context){
    20         super(context);
    21         inflate(getContext(), R.layout.item_select, this);
    22         cbx = (CheckBox)findViewById(R.id.cbx);
    23         name = (TextView)findViewById(R.id.name);
    24     }
    25     
    26     @Override
    27     public boolean isChecked() {
    28         return cbx.isChecked();
    29     }
    30 
    31     @Override
    32     public void setChecked(boolean arg0) {
    33         cbx.setChecked(arg0);
    34     }
    35 
    36     @Override
    37     public void toggle() {
    38         cbx.toggle();
    39     }
    40     
    41     public void setName(String name){
    42         this.name.setText(name);
    43     }
    44 
    45 }

    我的列表项只有一个显示名字的textview和一个代表单选状态的选择框,单选框我们需要取消他自身的点击效果,把它的状态交由列表项的点击去决定。所以,我们需要禁止checkbox的点击和焦点获取。代码如下--》

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="1" >
    
        <TextView
            android:id="@+id/name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".9" />
    
        <CheckBox
            android:id="@+id/cbx"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_weight=".1" 
            android:clickable="false"
            android:focusable="false"
            android:focusableInTouchMode="false"
            />
    
    </LinearLayout>

    【如何使用listview】很简单,在主页界面xml中定义listview,并设定choiceMode,此处为single,单选模式。

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:paddingBottom="@dimen/activity_vertical_margin"
     6     android:paddingLeft="@dimen/activity_horizontal_margin"
     7     android:paddingRight="@dimen/activity_horizontal_margin"
     8     android:paddingTop="@dimen/activity_vertical_margin"
     9     tools:context=".MainActivity" >
    10 
    11     <TextView
    12         android:layout_width="wrap_content"
    13         android:layout_height="wrap_content"
    14         android:text="@string/hello_world" />
    15     
    16     <Button android:layout_width="wrap_content"
    17         android:layout_height="wrap_content"
    18         android:onClick="choice"
    19         android:text="current"
    20         android:layout_below="@+id/lv"
    21         />
    22     
    23     <ListView android:layout_width="match_parent"
    24         android:layout_height="wrap_content"
    25         android:id="@+id/lv"
    26         android:choiceMode="singleChoice"
    27         />
    28   
    29 </RelativeLayout>

    【在主activity中的做了什么?】activity只是把listview的数据绑定到界面。使用adapter,此处是个内部类。adapter出奇的简单,只是设置了名字的显示而已,剩下的选择状态完全交由listview的机制和我们的自定义view.是不是很简单?快行动起来吧。

     1 package com.change.selectablelistviewdemo;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import android.app.Activity;
     7 import android.os.Bundle;
     8 import android.view.Menu;
     9 import android.view.View;
    10 import android.view.ViewGroup;
    11 import android.widget.BaseAdapter;
    12 import android.widget.ListView;
    13 import android.widget.Toast;
    14 
    15 /**
    16  * listview单选模式demo,
    17  * @author Change
    18  *
    19  */
    20 public class MainActivity extends Activity {
    21     List<String> names = new ArrayList<String>();
    22     ListView lv;
    23     SelAdapter adapter = new SelAdapter();
    24     @Override
    25     protected void onCreate(Bundle savedInstanceState) {
    26         super.onCreate(savedInstanceState);
    27         setContentView(R.layout.activity_main);
    28         lv = (ListView)findViewById(R.id.lv);
    29         initData();
    30         lv.setAdapter(adapter);
    31     }
    32     
    33     private void initData(){
    34         for(int i=0;i<10;i++){
    35             names.add("name"+i);
    36         }
    37     }
    38 
    39     @Override
    40     public boolean onCreateOptionsMenu(Menu menu) {
    41         // Inflate the menu; this adds items to the action bar if it is present.
    42         getMenuInflater().inflate(R.menu.main, menu);
    43         return true;
    44     }
    45     
    46     /**
    47      * 列表适配器,只需要设置view的内容,状态变化完全交由android机制和自定义view.是不是很简单?
    48      * @author Change
    49      *
    50      */
    51     class SelAdapter extends BaseAdapter{
    52 
    53         @Override
    54         public int getCount() {
    55             return names.size();
    56         }
    57 
    58         @Override
    59         public Object getItem(int arg0) {
    60             return names.get(arg0);
    61         }
    62 
    63         @Override
    64         public long getItemId(int arg0) {
    65             return arg0;
    66         }
    67 
    68         @Override
    69         public View getView(int arg0, View arg1, ViewGroup arg2) {
    70             if(null==arg1){
    71                 arg1 = new SelectItemView(MainActivity.this);
    72             }
    73             ((SelectItemView)arg1).setName(names.get(arg0));
    74             return arg1;
    75         }
    76         
    77         
    78     }
    79         public void choice(View v){
    80             int pos = lv.getCheckedItemPosition();
    81             if(ListView.INVALID_POSITION!=pos){
    82                 Toast.makeText(MainActivity.this, "current pos="+pos, Toast.LENGTH_SHORT).show();
    83             }
    84         }
    85 }

    【关键部分:取得当前选项】代码中标红的部分便可以轻松获得当前的选项,从此妈妈再也不担心我们不会选择了。

    【完整项目】在github中,地址:https://github.com/ChangeWu/SomePoject/tree/master/SelectableListViewDemo

  • 相关阅读:
    学习进度条
    学习进度条
    《软件需求模式》读书笔记04
    大型网站技术架构阅读笔记5
    大型网站技术架构阅读笔记4
    大型网站技术架构阅读笔记3
    大型网站技术架构阅读笔记2
    大型网站技术架构阅读笔记1
    《uml大战需求分析》阅读笔记06
    《uml大战需求分析》阅读笔记05
  • 原文地址:https://www.cnblogs.com/changewu/p/3866942.html
Copyright © 2020-2023  润新知