(源自:http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=16866&highlight=)
在android系统中,ListView的用法稍微复杂一点,配置Adpater就有几种方法,如ArrayAdapter,SimpleAdapter等。查了一些网上的相关例子,有很多都是用ListActivity ,然後用Adapter来显示布局。本例中没有用到ListActivity 。 ListView是在android中是一个经常用到的控件,ListView里面的每个子项Item可以使用一个字符串,也可以是一个组合控件,下面是本例将要实现的功能清单:
- 准备ListView要显示的数据,使用一维或多维 动态数组 保存数据;
- 构建 适配器,适配器就是Item数组,动态数组有多少元素就生成多少个Item;
- 把 适配器 添加到ListView,并显示出来;
- 在ListView的Item添加CheckBox并可以执行单击事件,设置单击事件,对应的Item显示对应Item的数据,通过getChildAt(0)找控件;
- 实现长按后弹出menu对话框效果;
本文所实现的ListView如下:
UI代码如下:
设置ListView的 Item样式 xml文件如下:
到这一步,顺便解答上面第4个问题:如何设置在 ListView中调协CheckBox之后还可以执行单击或长按事件,在Android中 CheckBox的点击事件优先级比ListView高,当页面一加载时,会默认聚焦在CheckBox上,为了防止这个问题出来,我们要在Android的控件上的属性加上Bool值:
android:focusable="false"
最后就是Java源代码,之后我再一一解答上面的所有问题:
- package cn.terry;
- import java.util.ArrayList;
- import java.util.HashMap;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.ContextMenu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.ContextMenu.ContextMenuInfo;
- import android.view.View.OnCreateContextMenuListener;
- import android.widget.*;
- import android.widget.AdapterView.OnItemClickListener;
- public class testListViewAcitivity extends Activity {
- private ListView myListView;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- myListView=(ListView)findViewById(R.id.ListView01);
- ArrayList<HashMap<String, Object>> listitem=new ArrayList<HashMap<String,Object>>();
- for(int i=0;i<10;i++)
- {
- HashMap<String, Object> map=new HashMap<String, Object>();
- map.put("ItemTitle", "文章"+i);
- map.put("ItemText", "Android 小项目"+i);
- listitem.add(map);
- }
- SimpleAdapter listitemAdapter=new SimpleAdapter(this,//上下文
- listitem, //数据
- R.layout.listview_style,//listItem的xml实现
- new String[]{"ItemTitle","ItemText"}, //从map的批定Key
- new int[]{R.id.topTextView,R.id.bottomTextView} //到要实现的控件上
- );
- myListView.setAdapter(listitemAdapter);
- myListView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
- long arg3) {
- // TODO Auto-generated method stub
- RelativeLayout lr=(RelativeLayout)arg1;
- TextView mText=(TextView)lr.getChildAt(1);
- Toast.makeText(testListViewAcitivity.this, "你点击了第"+arg2+"项的"+mText.getText().toString(),
- 1000).show();
- }
- });
- myListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
- // TODO Auto-generated method stub
- ListView lr=(ListView)v;
- RelativeLayout myte=(RelativeLayout)lr.getChildAt(0);
- TextView dd=(TextView)myte.getChildAt(1);
- menu.setHeaderIcon(R.drawable.icon);
- menu.setHeaderTitle(dd.getText().toString());
- menu.add(1, 0, 0, "高亮");
- menu.add(0, 1, 0, "置顶");
- }
- });
- }
- @Override
- public boolean onContextItemSelected(MenuItem item) {
- // TODO Auto-generated method stub
- String Temp="";
- switch (item.getItemId()) {
- case 0:
- Temp="高亮";
- break;
- case 1:
- Temp="置顶";
- break;
- default:
- break;
- }
- Toast.makeText(this, Temp+"处理", 1000).show();
- return super.onContextItemSelected(item);
- }
- }
- 准备ListView要显示的数据,使用一维或多维 动态数组 保存数据;
- 构建 适配器,适配器就是Item数组,动态数组有多少元素就生成多少个Item;
- 把 适配器 添加到ListView,并显示出来;
- 在ListView的Item添加CheckBox并可以执行单击事件,设置单击事件,对应的Item显示对应item的数据,通过getChildAt(0)找控件;
- 实现长按后弹出Menu对话框效果;
- ListView要显示的数据, 使用泛型可以方便我们对数据的取舍,使用HashMap,是为了得到key和value之后可以通过key去设置ListView各控件的值
项卡中我们用到的代码如下:- ArrayList<HashMap<String, Object>> listitem=new ArrayList<HashMap<String,Object>>();
- for(int i=0;i<10;i++)
- {
- HashMap<String, Object> map=new HashMap<String, Object>();
- map.put("ItemTitle", "文章"+i);
- map.put("ItemText", "Android 小项目"+i);
- listitem.add(map);
- }
- ListView支持多种适配器数据 如:SimpleAdapter和ArrayAdapter,本例使用的是SimpleAdapter,先看看simpleAdapter参数列表,
- android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
参数二:支持的数据源,如我们上文定义好的ArrayList<HashMap<String, Object>> ;
参数三:Item的xml实现,上边我们建立了ListView的Item样式XML,用法如:R.layout.listview_style
参数四:字符数组,大致意思可以这样理解,就是“从哪里来”,上文我们通过设置HashMap的键值,可以通过如下方式:new String[]{"ItemTitle","ItemText"},
参数五:整形数组,大致意思引用参数四可以这样理解,“从哪里来,到哪里去”通过事先from的键值to某个控件如:new int[]{R.id.topTextView,R.id.bottomTextView},注意,这里参数五的控件绑定数组要与参数四一一对应;
代码如下:- SimpleAdapter listitemAdapter=new SimpleAdapter(this,//上下文
- listitem, //数据
- R.layout.listview_style,//listItem的xml实现
- new String[]{"ItemTitle","ItemText"}, //从map的批定Key
- new int[]{R.id.topTextView,R.id.bottomTextView} //到要实现的控件上
- );
- 己经为SimpleAdapter设置好数组了。现在就到了把SimpleAdapter送到ListView身上就可以,代码如下:
- myListView.setAdapter(listitemAdapter);
- 代码简单,不需要过多解释;
单击后如何找到对应的项呢?通过调试发现,ListView的单击事件会自动定位到我们事先定义好的样式xml文件,之后我们要做的就是通过setOnItemClickListener自带的事件参数View把对应的控件找出来,之后我们可以做我们想做的事,通过getChildAt()的下标参数定位控件,然後转换成需要的可用控件,再取值或赋值,代码如下:- myListView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
- long arg3) {
- // TODO Auto-generated method stub
- RelativeLayout lr=(RelativeLayout)arg1;
- TextView mText=(TextView)lr.getChildAt(1);
- Toast.makeText(testListViewAcitivity.this, "你点击了第"+arg2+"项的"+mText.getText().toString(),
- 1000).show();
- }
- });
- 长按显示对话框的事件为:setOnCreateContextMenuListener,事件参数为:
- void cn.terry.testListViewAcitivity.onCreate(...).新建 OnCreateContextMenuListener() {...}.onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
- 指定: OnCreateContextMenuListener 中的 onCreateContextMenu(...)
- public abstract void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
- Since: API Level 1
- Called when the context menu for this view is being built. It is not safe to hold onto the menu after this method returns.
- Parameters
- menu The context menu that is being built
- v The view for which the context menu is being built
- menuInfo Extra information about the item for which the context menu should be shown. This information will vary depending on the class of v.
- menu.setHeaderIcon(R.drawable.icon);
- menu.setHeaderTitle(dd.getText().toString());
- menu.add(1, 0, 0, "高亮");
- menu.add(0, 1, 0, "置顶");
- boolean cn.terry.testListViewAcitivity.onContextItemSelected(MenuItem item)
方法得到用户点击的某个按钮,然後执行命令,参考代码如下:- public boolean onContextItemSelected(MenuItem item) {
- // TODO Auto-generated method stub
- String Temp="";
- switch (item.getItemId()) {
- case 0:
- Temp="高亮";
- break;
- case 1:
- Temp="置顶";
- break;
- default:
- break;
- }
- Toast.makeText(this, Temp+"处理", 1000).show();
- return super.onContextItemSelected(item);
- }
到此ListView的基本操作己经完成,但还存在问题:
- 在ListView上实现图片的动态切换不是很理想;
- 在ListView上实现长按效果时,想得到其中某一项的Item值无从下手,难道要重写View?
- 使用ArrayList<HashMap<String, Object>> listitem必需New,切记!;
本帖隐藏的内容需要回复才可以浏览
如果你有什麽疑问或者建议 你可以 QQ 285735942 或Email:terryyhl@gmail.com
本人博客文章地址:http://www.cnblogs.com/TerryBlog/archive/2010/06/05/1752325.html