Android进阶:ListView深入学习 choiceMode使用及自定义Adapter

首先看效果图:

Android进阶:ListView深入学习 choiceMode使用及自定义AdapterAndroid进阶:ListView深入学习 choiceMode使用及自定义Adapter

这个是多选模式的

首先看Layout配置文件

<?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" > <Button android:id="@+id/addButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="增加一个" /> <!-- android:scrollbarFadeDuration 一直显示滚动条 android:fastScrollEnabled 显示拖动块--> <ListView android:id="@id/android:list" android:layout_width="fill_parent" android:divider="#ee31ff5e" android:dividerHeight="1dp" android:choiceMode="multipleChoice" android:layout_height="fill_parent" android:fastScrollEnabled="true" android:focusable="true" android:scrollbarFadeDuration="0"/> </LinearLayout>

其中的android:choiceMode="multipleChoice"选项就是设置选择模式的,

他包括几个选择 CHOICE_MODE_MULTIPLE(多选), CHOICE_MODE_NONE(默认), CHOICE_MODE_SINGLE(单选)

这里还设置了divider

下面看代码

import java.util.ArrayList; import java.util.List; import java.util.Random; import android.app.ListActivity; import android.content.Context; import android.database.Cursor; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.View.OnTouchListener; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class ListViewDemo2 extends ListActivity{ private Cursor cursor; private Button button; private TextView textViewFooter; private TextView textViewHeader; private ArrayAdapter<String> adapter ; private int counter = 10; private List<String> list = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { list.add("aa"); list.add("bb"); list.add("cc"); list.add("dd"); list.add("ee"); list.add("ff"); list.add("gg"); list.add("hh"); list.add("ii"); list.add("jj"); list.add("kk"); list.add("ll"); list.add("mm"); list.add("nn"); super.onCreate(savedInstanceState); setContentView(R.layout.listviewdemo2); final ListView listView= (ListView) findViewById(android.R.id.list); textViewHeader = new TextView(this); textViewHeader.setGravity(Gravity.CENTER); textViewHeader.setTextSize(17); textViewFooter = new TextView(this); textViewFooter.setGravity(Gravity.CENTER); textViewFooter.setText("点击查看更多"); textViewFooter.setTextSize(18); textViewHeader.setText("全部信息("+list.size()+")"); listView.addHeaderView(textViewHeader); listView.addFooterView(textViewFooter); adapter = new ArrayAdapter<String>(ListViewDemo2.this,android.R.layout.simple_list_item_multiple_choice,list); listView.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String strtemp = ""; for(long ids :listView.getCheckItemIds()){ strtemp += ids+":"; } Toast.makeText(ListViewDemo2.this, ""+strtemp, Toast.LENGTH_LONG).show(); }}); setListAdapter(adapter); listView.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //获得当前点击位置的item序号 int itemnum = listView.pointToPosition((int)event.getX(), (int)event.getY()); //获得当前点击位置的RowId,为-1的除外 long temp = listView.pointToRowId((int)event.getX(), (int)event.getY()); Toast.makeText(ListViewDemo2.this, ""+itemnum+":"+temp, Toast.LENGTH_LONG).show(); break; default: break; } return false; }}); button = (Button) findViewById(R.id.addButton); button.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { Random random = new Random(); int position = random.nextInt(list.size()); list.add(position, ""+counter++); adapter.notifyDataSetInvalidated(); textViewHeader.setText("全部信息("+list.size()+")"); } }); } }

通过android已定义的ArrayAdapter来显示数据,效果如图,

里面添加了三个事件:

1、OnTouchListener 这里通过触摸点来定位这个list的position信息,包括两个方法 pointToPosition和pointToRowId,注意这两个方法的不同点,就是在状态为-1的数据是否计算的区别

2、OnItemClickListener 这里获得当前选择的条目 通过方法getCheckItemIds来获得

3、Button的点击,这里动态增加一条数据项,可以发现通过 getCheckItemIds来标记的选择项是通过位置来记录的,跟选择选项的内容无关,所以这里如果数据是动态的就要 需要注意

还有一个问题,刚开始我

new ArrayAdapter<String>(ListViewDemo2.this,android.R.layout.simple_list_item_multiple_choice,list);

这里构造方法传入的是一个数组, 这样就发现了一个问题:

在我点击button当然是数组数据增加一条,但是发现list中的数据没有变化,

这个是为什么呢,难道是传入的集合跟 ArrayAdapter中的集合不是同一个引用,那又发现了 ArrayAdapter中有add和insert方法,但用了之后发现有 java.lang.UnsupportedOperationException这个异常,android居然还没实现,真是奇怪啊,

后来详细看了下 ArrayAdapter这个类的构造方法,原来传入list跟数据操作不同,如果是list直接用该引用,如果传入数组,就会通过Arrays.asList()来创造一个新List 这个区别就太大了, 后来只能把数组改成List 真是郁闷啊

这里使用的是 ArrayAdapter ,那很多时候我们需要自定义Adater的,可能会处于数据处理,效率优化的考虑,

如果自定义Adapter如下

class MyAdapter extends BaseAdapter{ @Override public int getCount() { return list.size() ; } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv = new TextView(ListViewDemo2.this); tv.setText(list.get(position)); tv.setHeight(30); tv.setGravity(Gravity.CENTER); return tv; } }

这样定义显示的时候就会发现多选按钮框不见了,看 ArrayAdapter的实现就会发现,他所用的 android.R.layout.simple_list_item_multiple_choice布局用的是CheckedTextView组件

<?xml version="1.0" encoding="UTF-8"?> <CheckedTextView android:textAppearance="?textAppearanceLarge" android:gravity="center_vertical" android:id="@id/text1" android:paddingLeft="6.0dip" android:paddingRight="6.0dip" android:layout_width="fill_parent" android:layout_height="?listPreferredItemHeight" android:checkMark="?listChoiceIndicatorMultiple" xmlns:android="http://schemas.android.com/apk/res/android" />

所以这里如果用TextVew就不会显示选择提示框,其实这个组件就是TextView的子类

这里我们要用这个组件

class MyAdapter extends BaseAdapter{ @Override public int getCount() { return list.size() ; } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater)getApplication().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(android.R.layout.simple_list_item_multiple_choice, parent, false); TextView tv = (TextView)view; tv.setText(list.get(position)); tv.setHeight(30); tv.setGravity(Gravity.CENTER); return tv; } }

这样就正确显示了