android项目中需要制作一个类似于youtube的视频列表的界面,可采用ListView的方式实现,listView实现最好的方法就是配合Adapter(适配器)为其添数据,当然直接在java代码中为其添加数据也可以,但是不能实现动态数据的添加,比如说获取web服务器或者是其他程序中的数据。
关于Adapter:我们经常用"Men in the middle"中句话来描述它,也 就是“中间者”的意思。可以将它理解成数据和UI(View)之间的一个桥梁。
listview下的常用的adapter有:SimpleAdapter,ArrayAdapter,BaseAdapter等,其中我觉得最实用的就是BaseAdapter啦~
然后我们详细讲下这个。
BaseAdapter是个抽象类,继承它需要实现的方法有:
getCount(), getItem(int position),
getItemId(int position),
getView(int position, View convertView, ViewGroup parent)
首先通过代码来简单介绍下:
class MyImgAdapter extends BaseAdapter {可能还有些小盆于看不明白,不要着急,看了下面的解释你就明白了
@Override
public int getCount() {
// 根据他的返回值得到 listView的长度
return 0;
}
@Override
public Object getItem(int position) {
// 返回当前Item显示的数据,方便在Activity中的onItemClick方法中调用
return null;
}
@Override
public long getItemId(int position) {
// 长按返回当前Item显示的数据,方便在Activity中的onItemClick方法中调用
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// position就是位置从0开始,convertView是ListView中每一项要显示的view
// 通常return 的view也就是convertView
// parent就是父窗体了,也就是ListView了.
return null;
}
ListView绘制的过程如下:
第一步:系统在绘制ListView之前,将会先调用getCount方法来获取Item的个数。
第二步:开始绘制ListView列表,每绘制一个Item就会调用一次getView方法,在此方法内就可以引用事先定义好的xml来确定显示的效果并返回一个View对象作为一个Item显示出来。也正是在这个过程中完成了适配器的主要转换功能,把数据和资源以开发者想要的效果显示出来,一行行绘制,直到行数超过getCount()的返回值。
这两个方法是自定ListView显示效果中最为重要的,同时只要重写好了就两个方法,ListView就能完全按开发者的要求显示。而getItem和getItemId方法将会在调用ListView的响应方法的时候被调用到。所以要保证ListView的各个方法有效的话,这两个方法也得重写。比如:没有完成getItemId方法的功能实现的话,当调用ListView的getItemIdAtPosition()方法时将会得不到想要的结果,因为该方法就是调用了对应的适配器的getItemId方法。
接下来我们来写个简单的demo来实现下:
为了保证代码的高效性,以下的代码用到了一些优化策略,客官老爷们可以放心的直接用到项目中啦!!不过在写之前大家还需要了解下convertview和viewholder这两个东东。
convertview:官方解释是,The old view to reuse, if possible。原理上讲就是当ListView滑动的过程中 会有item被滑出屏幕 而不再被使用 这时候Android会回收这个条目的view 这个view也就是这里的convertView。
ViewHolder:
就是一个持有者的类,他里面一般没有方法,只有属性,作用就是一个临时的储存器,把你getView方法中每次返回的View存起来,可以下次再用。这样做的好处就是不必每次都到布局文件中去拿到你的View,提高了效率。
第一步:新建一个android项目,我的项目名字是BaseAdapterDemo
第二步:修改activity_main.xml文件
<RelativeLayout xmlns: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"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
第三步:编写ListView的xml文件,这里我只添加了一个TextView,大家也可以加入其他东西。比如一个列表有可以点击的图片(ImageButton),相关信息的TextView,以及一些Button。
<RelativeLayout xmlns: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"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
第四步:编写MainActivity.java代码,在onCreate方法下面插入以下代码
class MyAdapter extends BaseAdapter {
Context mContext;// 用于接收传递过来的Context对象
LayoutInflater inflater;
public MyAdapter(Context context) {
mContext = context;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
// 这里我就返回8了,也就是一共有8项数据项
return 8;
}
@Override
public Object getItem(int position) {
// 返回当前Item显示的数据,方便在Activity中的onItemClick方法中调用
return position;
}
@Override
public long getItemId(int position) {
// 长按返回当前Item显示的数据,方便在Activity中的onItemClick方法中调用
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView != null) {
// 当item1被移除屏幕的时候,我们会重新new一个View给新显示的item 而如果使用了这个convertView
// 我们其实可以复用它,这样就省去了new View的大量开销
convertView = inflater.inflate(R.layout.listitem1, parent, false);
viewHolder = new ViewHolder();
viewHolder.textView = (TextView)convertView.findViewById(R.id.textview);
convertView.setTag(viewHolder);
convertView.setTag(viewHolder);
} else {
// 没有供复用的view 按一般的做法新建view
viewHolder = (ViewHolder) convertView.getTag();
}
//配置每个list的数据
convertView.textView.setText(Integer.toString(position));
return convertView;
}
}
// 定义的ViewHolder,非常简单,里面只有一个TextView
class ViewHolder {
TextView textView;
}
第五步:运行项目就可以看到效果啦。
参考博文:
listview加载性能优化ViewHolder
如果有问题欢迎邮件交流:我的邮箱racechao@gmail.com