Android学习笔记:ListView及BaseAdapter使用
ListView是Android中常用的重要组件之一,基本上所有软件基本都会使用ListView,所以要对ListView非常熟悉。
先看看程序效果图:
ListView的样式很多,有纯文字型,带图片显示,带按钮的等等。本次演示一个带图片的ListView。
①布局文件:
在ListView程序中,布局文件相比其他普通控件会多出至少一个,其原因是还需要一个关于ListView里面内容条目的布局文件。
内容条目的布局文件listview_item.xml :
<?xmlversion="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="?android:attr/listPreferredItemHeight"><ImageViewandroid:id="@+id/id_p_w_picpathview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/ic_launcher"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"/><TextViewandroid:id="@+id/id_tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@id/id_p_w_picpathview"android:layout_marginLeft="15dp"android:layout_alignParentTop="true"android:textSize="22sp"android:textStyle="bold"android:text="title"/><TextViewandroid:id="@+id/id_tv_desc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@id/id_p_w_picpathview"android:layout_below="@id/id_tv_title"android:layout_marginLeft="15dp"android:textSize="18sp"android:text="longlongagostory"/></RelativeLayout>
看了代码应该就明白了我上面说的ListView内容条目的布局指的就是
这样一条条的布局文件
另外一个布局文件,整个android程序的总体布局文件activity_main.xml :
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.example.testlistview.MainActivity"><LinearLayoutandroid:id="@+id/listview_ll"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ListViewandroid:id="@id/android:list"android:layout_width="match_parent"android:layout_height="wrap_content"android:drawSelectorOnTop="true"android:scrollbars="vertical"/></LinearLayout></LinearLayout>
只有一个<ListView /> 其中scrollbars="vertical"意思是如果条目很多,滚动时会滚动条是垂直的。
②Android代码
MainActivity.java
packagecom.example.testlistview;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importandroid.app.ListActivity;importandroid.content.Context;importandroid.os.Bundle;importandroid.widget.SimpleAdapter;/***注意继承的是ListActivity*@authorjam**/publicclassMainActivityextendsListActivity{privateList<Map<String,Object>>list;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);list=newArrayList<Map<String,Object>>();Map<String,Object>map1=newHashMap<String,Object>();Map<String,Object>map2=newHashMap<String,Object>();Map<String,Object>map3=newHashMap<String,Object>();//三项,分别是图片,大标题,内容map1.put("avatar",R.drawable.add_option);map1.put("user_name","zhangsan");map1.put("user_ip","192.168.1.0");map2.put("avatar",R.drawable.add_pic);map2.put("user_name","lisi");map2.put("user_ip","192.168.1.1");map3.put("avatar",R.drawable.ic_launcher);map3.put("user_name","wangwu");map3.put("user_ip","192.168.1.2");list.add(map1);list.add(map2);list.add(map3);//使用SimpleAdapter的方法/***四个参数*第一个参数是当前的Context*第二个参数,是数据来源list*第三个第四个相当于键值对的关系*//*setListAdapter(newSimpleAdapter(getApplicationContext(),list,R.layout.listview_item,newString[]{"user_name","user_ip"},newint[]{R.id.id_tv_title,R.id.id_tv_desc}));*///设置AdaptersetListAdapter(newMyBaseAdapter(getApplicationContext(),list));}}
其中MyBaseAdapter.java代码:
packagecom.example.testlistview;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importandroid.content.Context;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.BaseAdapter;importandroid.widget.ImageView;importandroid.widget.TextView;/***继承BaseAdapter*相对于SimpleAdapter来说显得麻烦,但带来了更多好处*@authorjam**/publicclassMyBaseAdapterextendsBaseAdapter{privateLayoutInflatermyInfalater;privateList<Map<String,Object>>list;publicMyBaseAdapter(Contextcontext,List<Map<String,Object>>list){super();this.list=list;myInfalater=LayoutInflater.from(context);}@OverridepublicintgetCount(){returnlist.size();}@OverridepublicObjectgetItem(intposition){returnposition;}@OverridepubliclonggetItemId(intpositionId){returnpositionId;}//重要的重写方法@OverridepublicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ViewHolderviewHolder;if(convertView==null){convertView=myInfalater.inflate(R.layout.listview_item,null);viewHolder=newViewHolder();viewHolder.avatar=(ImageView)convertView.findViewById(R.id.id_p_w_picpathview);viewHolder.title=(TextView)convertView.findViewById(R.id.id_tv_title);viewHolder.desc=(TextView)convertView.findViewById(R.id.id_tv_desc);convertView.setTag(viewHolder);}else{viewHolder=(ViewHolder)convertView.getTag();}viewHolder.avatar.setBackgroundResource((Integer)list.get(position).get("avatar"));viewHolder.title.setText((CharSequence)list.get(position).get("user_name"));viewHolder.desc.setText((CharSequence)list.get(position).get("user_ip"));returnconvertView;}privateclassViewHolder{ImageViewavatar;TextViewtitle;TextViewdesc;}}
说明
BaseAdapter是一个很常用的Adapter,是一个抽象类,需要重写很多方法。
在Adapter中先调用getCount()方法,得到ListView的长度,根据这个长度逐一绘制ListView的每一行
onvertView相当于一个缓存,开始为0,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只需要更新数据就可以了,这样大大节省了系统资料的开销
ViewHolder的应用 :
View的findViewById()方法也是比较耗时的,因此需要考虑只调用一次,之后就用convertView.getTag();方法来获得ViewHolder对象。
通俗的说,inflate就相当于将一个xml中定义的布局找出来.
因为在一个Activity里如果直接用findViewById()的话,对应的是setConentView()的那个layout里的组件.
因此如果你的Activity里如果用到别的layout,比如对话框上的layout,你还要设置对话框上的layout里的组件(像图片ImageView,文字TextView)上的内容,你就必须用inflate()先将对话框上的layout找出来,然后再用这个layout对象去找到它上面的组件。
另外这里有些BaseAdapter相关资料:
http://www.open-open.com/lib/view/open1339485728006.html
http://android.tgbus.com/Android/tutorial/201104/348009.shtml
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。