【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView
ListView控件以垂直布局方式显示子view。系统的android.app.ListActivity已经实现了一个只含有一个ListView的Activity,并通过setListAdapter()方法来管理adapter。我们可以通过扩展ListActivity来实现。
我们要在整个屏幕上显示ListView,我们直接继承使用ListActivity,不需要在定义自己的layout XML文件,我们在上一学习中已经进行了相关小例子的演示。
点击List的item触发
我们沿用之前呈现联系人姓名的例子,在上面加上点击触发的处理。以前我们试过内部类调用和对象调用,这次也采用对象调用。
public class UiAdapterDemo extends ListActivity implements OnItemClickListener{
protected void onCreate(Bundle savedInstanceState) {
…… //代码见 Pro Android学习笔记(十八):用户界面和控制(6):Adapter和AdapterView 的第一个小例子
ListView lv = getListView(); //获取ListView控件
lv.setOnItemClickListener(this); //稍微做点变化
Log.d("UiAdapterDemo","Listview is " + lv.toString());
}
//请配合下面运行的结果图来看各参数的含义
public void onItemClick(AdapterView<?> parent, View view, int position, long rowId) {
// parent本例就是ListView,可以验证和listview是同一对象
Log.d("onItemClick","parent : " + parent.toString());
// position是在list的位置,即子view的序号,从0还是计算。rowId是数据源的序号,与具体的数据源方式有关,如果来自cursor,这是_ID,如果来自array,则是array[rowId]。
Log.d("onItemClick","position = " + position + " Row id is " + rowId);
//在层次结构上,一般是ListView –>子View(Layout)—>子View中的具体控件,而本例的结构很简单为ListView –> 子View(TextView),我们可以通过这两种方式来获取具体控件的信息
//方式1:ListView –> 子View(TextView) view就是子view,本例是android.R.layout.simple_list_item_1,就是一个简单的TextView,所以子view就是TextView。
Log.d("onItemClick","view : " + view.toString());
Log.d("onItemClick","name : " + ((TextView)view).getText());
//方式2: ListView –>子View(Layout)—>子View中的具体控件也可以按ApdaterView的结构,将子view视为是一个容器,通过findViewById找到里面相应的控件,两种方式的结果是一样。
TextView tv = (TextView) view.findViewById(android.R.id.text1);
Log.d("onItemClick","tv : " + tv.toString());
Log.d("onItemClick","name : " + tv.getText());
//点击触发打开该联系人,在content Provider的情况下,rowId就是_ID,但如果是ArrayAdapter,则rowId就是在数组的位置,即position和rowId会一样。
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, rowId);
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
}
}
在这个例子中,我们在联系人程序中修改联系人信息,发现ListView会自动同步,这是SimpleCursorAdapter带来的好处,然而,如果我们使用ArrayAdapter,则需要notifyDataSetChanged( )。
添加其他控件,以及获取item数据
<?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="vertical" >
<ListView android:id="@android:id/list" <!-- ListActivity将使用该ID的listview,如果要extends ListActivity -->
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" /> <!-- 设置layout_height=0dip和layout_weight=1,目的是确保屏幕有足够的地方显示其他控件,本例是确保button出现在屏幕的下方,即时List的items数很多,需要翻屏显示,button也能一直出现在最下方 -->
<Button android:id="@+id/ui_listbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/submit"
android:onClick="submitFunc" />
</LinearLayout>
相关代码和运行结果如下:
public class UiAdapterDemo2 extends ListActivity{
private int idCol;
private int nameCol;
private int timesContacted;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ui_add_listview); //使用我们自定义的layout
CursorLoader cursorLoader = new CursorLoader(getApplicationContext(),
ContactsContract.Contacts.CONTENT_URI,
null, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
cur = cursorLoader.loadInBackground();
//获取Cusor数据源中各项关键信息的列index,用于后面的信息检索
idCol = cur.getColumnIndex(ContactsContract.Contacts._ID);
nameCol = cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
timesContactedCol = cur.getColumnIndex(ContactsContract.Contacts.TIMES_CONTACTED);
String[] cols = new String[]{ContactsContract.Contacts.DISPLAY_NAME};
int[] views = new int[]{android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_multiple_choice, //这是子View的layout,打开源代码文件,我们看到这是id为android.R.id.text1(这就是int[] views所填的值)的CheckedTextView,CheckedTextView是TextView的子类,样子是一个TextView和一个CheckBox
cur, cols, views,CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
this.setListAdapter(adapter);
ListView lv = getListView();
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); //设置listview模式,使用多选模式。缺省是CHOICE_MODE_NONE,此外还有CHOICE_MODE_SINGLE(相应的,我们在adapter中设置sub view可以用android.R.layout.simple_list_item_single_choice。
}
public void submitFunc(View v){
ListView lv = getListView();
SparseBooleanArray positionChecked = lv.getCheckedItemPositions(); // 来自android.widget.AbsListView的函数,用于存放多选择模式listview的选择情况
for(int i = 0 ; i < lv.getCount() ; i ++){
Log.d("listAddControl","position [" + i +"] " + positionChecked.get(i));
}
for(int i = 0 ; i < lv.getCount(); i++){ //找出item的对应的数据源,显示更为详细的信息
if(positionChecked.get(i)){
cur.moveToPosition(i); //在这里也可以使用AdapterView的 Object getItemAtPosition(int position),在Content Provider,中返回的是CursorWrapper,返回信息格式与具体的数据源相关。本例也可以使用CursorWrapper cw = (CursorWrapper) lv.getItemAtPosition(i);
Log.d("listAddControl","[" + i +"]: _id=" + cur.getLong(idCol) + " " + cur.getString(nameCol)
+ " Contact times:" + cur.getInt(timesContactedCol));
}
}
}
}
我们换一种方式来写summitFunc,代码如下:
public void submitFunc(View v){
if(!adapter.hasStableIds()){ //询问在数据变更时,ID会不会也随之变化。true表示不变
Log.d("listAddControl","Not the same id always refers to the same object.");
return;
}
ListView lv = getListView();
long[] viewItems = lv.getCheckedItemIds(); //这是本次实验的内容,本例是Content provider,则返回为_ID。在使用getCheckedItemIds(),建议先用hasStabledIds来确认获得的Id值是否稳定不变。。
for (int i = 0 ; i < viewItems.length ; i ++){
Log.d("listAddControl", "cheked Item Id : " + viewItems[i]);
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, viewItems[i]);
Log.d("listAddControl", uri.toString());
}
}
在这个例子中,我们获得了_ID,就可以构造URI,从provider中直接读取信息,因此,我们就没有必要将联系的所有信息都放置在cursor中,不需要占那么所资源。注意,_ID是必须要读取。
String[] projects = {ContactsContract.Contacts._ID,ContactsContract.Contacts.DISPLAY_NAME};
CursorLoader cursorLoader = new CursorLoader(getApplicationContext(),
ContactsContract.Contacts.CONTENT_URI,
projects, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
相关链接: 我的Android开发相关文章
【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView的更多相关文章
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
- 【转】 Pro Android学习笔记(九四):AsyncTask(3):ProgressDialog
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Progress Dialog小例子 我们 ...
- 【转】 Pro Android学习笔记(九二):AsyncTask(1):AsyncTask类
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在Handler的学习系列中,学习了如何h ...
- 【转】 Pro Android学习笔记(九三):AsyncTask(2):小例子
目录(?)[-] 继承AsyncTask UI操作接口 使用AsyncTask 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn. ...
- 【转】Pro Android学习笔记(九):了解Content Provider(下下)
Content provider作为信息的读出,比较常见的还有文件的读写,最基础的就是二进制文件的的读写,例如img文件,音频文件的读写.在数据库中存放了该文件的路径,我们可以通过ContentPro ...
- 【转】 Pro Android学习笔记(九一):了解Handler(5):组件生命
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 对于activity,消息是在OnCrea ...
- 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge
目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...
- 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout
目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...
- 【转】 Pro Android学习笔记(二二):用户界面和控制(10):自定义Adapter
目录(?)[-] 设计Adapter的布局 代码部分 Activity的代码 MyAdapter的代码数据源和构造函数 MyAdapter的代码实现自定义的adapter MyAdapter的代码继续 ...
随机推荐
- Django中日志管理
在settings中设置日志的相关信息,然后再逻辑代码区就可以保存相应的信息了 #简单设置: LOGGING = { 'version': 1, 'disable_existing_loggers': ...
- spring ioc和aop理解
1.IOC 表示控制反转. 简单点说就是原来的对象是在要使用之前通过在代码里通过new Something()的方式创建出来的: IOC则是由spring容器创建同一创建,在程序要使用到该对象的时候, ...
- error in static/js/xxx.js from UglifyJs Unpected token: punc() [static/js/xxx.js]
出现问题 使用vue+element-ui+webpack开发项目时,Jenkins构建出现报错error in static/js/xxx.js from UglifyJs Unpected tok ...
- 使用Pydoc生成文档
Python中本身带有很多实用的工具,如pydoc.pydoc模块主要用来从Python模块中提取信息并生成文档. 使用方法 在Windows和Linux下的使用方法有些区别. Windows pyt ...
- Win7打开新的文件夹总会以新窗口的形式打开
首先可以在 组织-->文件夹和搜索选项 中设置“在同一窗口中打开每个文件夹” 如果设置后不起作用还可以 管理员方式执行以下两条命令 在开始菜单-运行中输入regsvr32 "%Sy ...
- POJ 3070 矩阵mob
. 矩阵高速幂想法与快速幂相同 #include<iostream> #include<cstdio> #include<cstring> #define MOD ...
- 使用vsftp搭建ftp服务
第一步:安装vsftp pam db4 yum install vsftpd pam* db4*-y ================================================= ...
- 剑指offer之 二叉搜索树的后续遍历序列
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. public class Solution { ...
- ruanjiangongcheng1
软体工程的方法有很多方面的意义.包括专案管理,分析,设计,程序的编写,测试和质量控制. 软体设计方法可以区别为重量级的方法和轻量级的方法.重量级的方法中产生大量的正式文档. 著名的重量级开发方法包括I ...
- JavaWeb -- 会话, Cookie 和 Session
1. 会话 •Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去.这样,web资源处理的就是 ...