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

android列表选择模式的实现

时间: 2024-11-03 22:08:48

android列表选择模式的实现的相关文章

Android——列表选择框(Spinner)

通常情况下,如果列表选择框中要显示的列表项是可知的,那么可以将其保存在数组资源文件中,然后通过数组资源来为列表选择框指定列表项.这样就可以在不编写Java代码的情况下实现一个下拉选择框. 1.在布局文件中添加一个<spinner>标记,并为其指定android:entries属性,具体代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q

Android 自学之列表选择框Spinner

列表选择框(Spinner)与Swing编程里面的Spinner不同,这里的Spinner其实就是一个列表选项框. Spinner是ViewGroup的间接子类,因此他也可作为容器使用. Spinner支持的常用XML属性和说明: XML属性 说明 android:prompt 设置该列表框的提示 android:entries 使用数组资源设置该下拉列表框的列表项目 啥都不说了我们看看代码: layout/main.xml 1 <?xml version="1.0" encod

Android开发系列(二十一):Spinner的功能和用法以及实现列表选择框

Spinner是一个列表选择框,相当于弹出一个菜单供用户进行选择. Spinner继承AdapterView Spinnet支持的XML的属性: android:entries:使用数组资源设置该下拉列表框的列表项目 android:popupBackground:设置下拉列表框的背景色 (一般这两个比较常用一点) 用Spinner用两种方法: 第一.已经确定下拉列表里的列表项,只要为Spinner指定android:entries属性就可以实现Spinner. 第二.如果程序需要在运行时动态地

Android开发系列(二十一):Spinner的功能和使用方法以及实现列表选择框

Spinner是一个列表选择框.相当于弹出一个菜单供用户进行选择. Spinner继承AdapterView Spinnet支持的XML的属性: android:entries:使用数组资源设置该下拉列表框的列表项目 android:popupBackground:设置下拉列表框的背景色 (一般这两个比較经常使用一点) 用Spinner用两种方法: 第一.已经确定下拉列表里的列表项,仅仅要为Spinner指定android:entries属性就能够实现Spinner. 第二.假设程序须要在执行时

Android Spinner列表选择框

Spinner Spinner是一个下拉列表,通常用于选择一系列可选择的列表项,它可以使用适配器,也可以直接设置数组源. 1.直接设置数组源 在res/values/strings.xml中设置数组源 1 <string-array name="selector"> 2 <item >学生证</item> 3 <item >结婚证</item> 4 <item >军官证</item> 5 <ite

安卓组件------列表选择框

安卓提供的列表选择框(Spinner)相当于web端用户注册时的选择下拉框,比如注册候选择省份城市等.如下图便是一个列表选择框 下拉列表的列表选择项能够通过xml文件的android:entries属性指定,或是在java代码中导入,属性android:prompt是列表项的标题. 一    列表项数据:       实际运用当中,很多下拉列表项的数据实际是可知的,可以放在xml资源文件中.这时,开发者可以通过xml属性进行指定数据. 除了资源文件之外,开发者还能够使用适配器适配数据源.(适配器

android MVVM开发模式(一)

android MVVM开发模式 概念 mvvm 是一个在 mvp 架构上修改,目标是将view的一些更改,跟model关联起来,使得model的数据改变,直接通知到view上面来,从而解决mvp架构里面的v-p之间的接口太重问题. 所以mvvm的核心解决问题为:使得v-p直接的关系弱化,使用绑定方式(dataBinding)直接将model的改变反馈到view上面. 关于完整的dataBinding讲解,请看这里 https://github.com/LyndonChin/MasteringA

Android设计模式—策略模式

1.策略模式概念 定义一系列算法,把他们独立封装起来,并且这些算法之间可以相互替换.策略模式主要是管理一堆有共性的算法,客户端可以根据需要,很快切换这些算法,并且保持可扩展性. 策略模式的本质:分离算法,选择实现. 2.策略模式实现 下面针对策略模式说一个小型的实现例子,个人觉得学习设计模式,最好的方法是看看设计模式概念,然后先看看简单的模式实现的例子.策略模式实现起来,主要需要3部分:抽象接口.实现算法.上下文. //算法的接口 public interface PriceStrategy {

Android MVPR 架构模式-Part1

Android MVPR 架构模式-Part1 原文链接 : MVPR: A FLEXIBLE, TESTABLE ARCHITECTURE FOR ANDROID (PT. 1) 原文作者 :Matthew Dupree 译文出自 : 开发技术前线 www.devtf.cn 译者 : chaossss 校对者: Mr.Simple 状态 : 完成 全面的单元测试能提高内部系统的代码质量,因为系统的每一个组件都需要被测试,因此每个单元都需要在系统外被构建,在测试环境中进行测试.对对象进行单元测试