Android基本控件之ListView(二)<ListView优化>
2016-12-08 08:46
417 查看
之前我们说到ListView的基本用法。但是,有很多的时候会额外的占用一些内存,从而消耗了性能。既然有消耗性能的可能,那么我们就对其做出相应的优化
我们首先来说说优化的步骤:
第一步、将宽和高设置为填充父窗体,有助于填充item时,避免重复渲染ListView,而导致重复多次调用ListView
第二步、判断getView()方法中的convertView是否为空,如果为空就创建View,不为空就重复使用View
第三步、创建类ViewHolder来解决每次重复查找convertView中的组件
然后,我们就来详细的说一说具体应该如何去优化:
我们首先要创建一个内部类叫做ViewHolder,并在类中维护在item中的各种控件
然后,我们在getView()方法中去维护一个ViewHolder。
然后,我们需要加上一个判断,去判断convertView是否为空,如果为空就证明屏幕显示的还是之前的,并没有新的item进入到屏幕中。
那么,我们需要在其中给convertView赋值(通过布局填充器去实例化)
然后,我们实例化一个ViewHolder
然后,我们需要调用一个setTag()方法把ViewHolder放入到convertView中。
如果convertView不为空,就证明屏幕上显示的item有更新,那么我们就设置item中各个控件要显示的数据。
在此之前,我们需要通过getTag()方法从convertView中获取到Viewholder
最后,返回convertView
优化的过程就是这样。接下来,我们来使用上次的代码再实现一下优化。
我们还是来顺一下思路:
布局文件:
我们需要每个item的布局(一个图标<ImageView>, 一个标题<TextView>,一个内容<TextView>),和主界面布局<ListView>
Activity中:
首先,按照套路,获取控件,设置数据源,设置适配器,设置点击事件
然后我们自定义适配器继承BaseAdapter,并实现其中的方法
在getView方法中先判断convertView是否为空,如果为空就创建一个,如果不为空就设置值
然后,我们定义一个类叫做ViewHodler,并在其中维护item布局中的各种控件
接下来,我们按照我们所想的,来做一个具体的实现:
我们先来看item的布局:
接下来,我们来看主界面布局文件:
现在,我们的布局文件就准备好了。
接下来,我们来看Activity中的状态:
我们先准备数据源
然后,我们找到控件:
然后,我们设置适配器:
这里看到了一个MyAdapter,我们一会再说
接下来,我们设置点击事件:
接下来,我们来看自定义适配器:
该自定义适配器继承了BaseAdapter,并实现其中的4种方法
在重写四种方法之前,我们先维护一个上下文和一个布局填充器,并为其提供一个构造方法去获得一个布局适配器。
然后,我们来重写那四个方法:
1.getCount
2.getItem
3.getItemId
4.getView
然后,我们来定义一个内部类,叫做ViewHolder
我们来简单的整理一个思路
首先,我们定义一个内部类叫做ViewHolder
然后,我们在getView方法中去判断convertView是否为空,如果为空,就通过布局填充器把每个item的布局添加到convertView中。
如果不为空就重复的利用这个布局,并在其中设置数据。
最后,返回convertView
这样,我们的ListView的优化就完成了。
源码奉上:
让程序写入生命,将代码融入灵魂
-------smile、zj
我们首先来说说优化的步骤:
第一步、将宽和高设置为填充父窗体,有助于填充item时,避免重复渲染ListView,而导致重复多次调用ListView
第二步、判断getView()方法中的convertView是否为空,如果为空就创建View,不为空就重复使用View
第三步、创建类ViewHolder来解决每次重复查找convertView中的组件
然后,我们就来详细的说一说具体应该如何去优化:
我们首先要创建一个内部类叫做ViewHolder,并在类中维护在item中的各种控件
然后,我们在getView()方法中去维护一个ViewHolder。
然后,我们需要加上一个判断,去判断convertView是否为空,如果为空就证明屏幕显示的还是之前的,并没有新的item进入到屏幕中。
那么,我们需要在其中给convertView赋值(通过布局填充器去实例化)
然后,我们实例化一个ViewHolder
然后,我们需要调用一个setTag()方法把ViewHolder放入到convertView中。
如果convertView不为空,就证明屏幕上显示的item有更新,那么我们就设置item中各个控件要显示的数据。
在此之前,我们需要通过getTag()方法从convertView中获取到Viewholder
最后,返回convertView
优化的过程就是这样。接下来,我们来使用上次的代码再实现一下优化。
我们还是来顺一下思路:
布局文件:
我们需要每个item的布局(一个图标<ImageView>, 一个标题<TextView>,一个内容<TextView>),和主界面布局<ListView>
Activity中:
首先,按照套路,获取控件,设置数据源,设置适配器,设置点击事件
然后我们自定义适配器继承BaseAdapter,并实现其中的方法
在getView方法中先判断convertView是否为空,如果为空就创建一个,如果不为空就设置值
然后,我们定义一个类叫做ViewHodler,并在其中维护item布局中的各种控件
接下来,我们按照我们所想的,来做一个具体的实现:
我们先来看item的布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <ImageView android:id="@+id/iv_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/tv_title" android:layout_marginTop="10dp" android:layout_toRightOf="@+id/iv_icon" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="这是标题" android:textSize="20sp"/> <TextView android:id="@+id/tv_content" android:layout_toRightOf="@+id/iv_icon" android:layout_below="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="这是内容"/> </RelativeLayout>
接下来,我们来看主界面布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="application.smile.listview.MainActivity"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
现在,我们的布局文件就准备好了。
接下来,我们来看Activity中的状态:
我们先准备数据源
//存储文字的数组 private String [] names ={"郭嘉", "黄月英", "华佗", "刘备", "陆逊", "吕布", "吕蒙", "马超", "司马懿", "孙权", "孙尚香", "夏侯惇", "许褚", "杨修", "张飞", "赵云", "甄姬", "周瑜", "诸葛亮"}; //存储图片的数组 private int [] images = {R.mipmap.guojia, R.mipmap.huangyueying, R.mipmap.huatuo, R.mipmap.liubei, R.mipmap.luxun, R.mipmap.lvbu, R.mipmap.lvmeng, R.mipmap.machao, R.mipmap.simayi, R.mipmap.sunquan, R.mipmap.sunshangxiang, R.mipmap.xiahoudun, R.mipmap.xuchu, R.mipmap.yangxiu, R.mipmap.zhangfei, R.mipmap.zhaoyun, R.mipmap.zhenji, R.mipmap.zhouyu, R.mipmap.zhugeliang};
然后,我们找到控件:
//找到控件 ListView listView = (ListView) findViewById(R.id.listView);
然后,我们设置适配器:
//设置适配器 listView.setAdapter(new MyAdapter(this));
这里看到了一个MyAdapter,我们一会再说
接下来,我们设置点击事件:
//设置点击事件 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //弹出吐司 Toast.makeText(MainActivity.this, "点我了?我是" + names[position], Toast.LENGTH_SHORT).show(); } });
接下来,我们来看自定义适配器:
该自定义适配器继承了BaseAdapter,并实现其中的4种方法
在重写四种方法之前,我们先维护一个上下文和一个布局填充器,并为其提供一个构造方法去获得一个布局适配器。
//维护一个上下文,为了得到布局填充器 private Context context; //维护一个布局填充器,为了得到每个item 的布局 private LayoutInflater layoutInflater; public MyAdapter(Context context) { //通过构造方法获取布局填充器对象 layoutInflater = LayoutInflater.from(context); }
然后,我们来重写那四个方法:
1.getCount
//该方法是总共有多少个item @Override public int getCount() { return names.length; }
2.getItem
//该方法是得到每个item的值 @Override public Object getItem(int position) { return names[position]; }
3.getItemId
//该方法是得到每个item的id @Override public long getItemId(int position) { return position; }
4.getView
//该方法是获得视图,也是这些里面最重要的方法 @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { //首先,我们通过布局填充器获得item的布局 convertView = layoutInflater.inflate(R.layout.item_layout, null); //实例化ViewHodler viewHolder = new ViewHolder(); //根据item的布局找到图片 viewHolder.iv_icon = (ImageView) convertView.findViewById(iv_icon); //根据item的布局找到标题 viewHolder.tv_title = (TextView) convertView.findViewById(tv_title); //根据item的布局找到内容 viewHolder.tv_content = (TextView) convertView.findViewById(tv_content); //设置tag标记 convertView.setTag(viewHolder); } viewHolder = (ViewHolder) convertView.getTag(); //设置图片源(也就是我们装图片的那个数组) viewHolder.iv_icon.setImageResource(images[position]); //设置标题文字 viewHolder.tv_title.setText(names[position]); //设置内容文字 viewHolder.tv_content.setText("我是" + names[position]); //返回item的布局 return convertView; }
然后,我们来定义一个内部类,叫做ViewHolder
class ViewHolder { ImageView iv_icon; TextView tv_title; TextView tv_content; }
我们来简单的整理一个思路
首先,我们定义一个内部类叫做ViewHolder
然后,我们在getView方法中去判断convertView是否为空,如果为空,就通过布局填充器把每个item的布局添加到convertView中。
如果不为空就重复的利用这个布局,并在其中设置数据。
最后,返回convertView
这样,我们的ListView的优化就完成了。
源码奉上:
public class MainActivity extends AppCompatActivity {
//存储文字的数组
private String[] names = {"郭嘉", "黄月英", "华佗", "刘备", "陆逊", "吕布", "吕蒙", "马超", "司马懿", "孙权",
"孙尚香", "夏侯惇", "许褚", "杨修", "张飞", "赵云", "甄姬", "周瑜", "诸葛亮"};
//存储图片的数组
private int[] images = {R.mipmap.guojia, R.mipmap.huangyueying, R.mipmap.huatuo, R.mipmap.liubei, R.mipmap.luxun, R.mipmap.lvbu, R.mipmap.lvmeng,
R.mipmap.machao, R.mipmap.simayi, R.mipmap.sunquan, R.mipmap.sunshangxiang, R.mipmap.xiahoudun, R.mipmap.xuchu, R.mipmap.yangxiu,
R.mipmap.zhangfei, R.mipmap.zhaoyun, R.mipmap.zhenji, R.mipmap.zhouyu, R.mipmap.zhugeliang};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
ListView listView = (ListView) findViewById(R.id.listView);
//设置适配器
listView.setAdapter(new MyAdapter(this));
//设置点击事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//弹出吐司
Toast.makeText(MainActivity.this, "点我了?我是" + names[position], Toast.LENGTH_SHORT).show();
}
});
}
/**
* 自定义适配器,继承BaseAdapter
*/
class MyAdapter extends BaseAdapter {
//维护一个上下文,为了得到布局填充器
private Context context;
//维护一个布局填充器,为了得到每个item 的布局
private LayoutInflater layoutInflater;
public MyAdapter(Context context) {
//通过构造方法获取布局填充器对象
layoutInflater = LayoutInflater.from(context);
}
//该方法是总共有多少个item @Override public int getCount() { return names.length; }
//该方法是得到每个item的值
@Override
public Object getItem(int position) {
return names[position];
}
//该方法是得到每个item的id
@Override
public long getItemId(int position) {
return position;
}
//该方法是获得视图,也是这些里面最重要的方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
//首先,我们通过布局填充器获得item的布局
convertView = layoutInflater.inflate(R.layout.item_layout, null);
//实例化ViewHodler
viewHolder = new ViewHolder();
//根据item的布局找到图片
viewHolder.iv_icon = (ImageView) convertView.findViewById(iv_icon);
//根据item的布局找到标题
viewHolder.tv_title = (TextView) convertView.findViewById(tv_title);
//根据item的布局找到内容
viewHolder.tv_content = (TextView) convertView.findViewById(tv_content);
//设置tag标记
convertView.setTag(viewHolder);
}
viewHolder = (ViewHolder) convertView.getTag();
//设置图片源(也就是我们装图片的那个数组)
viewHolder.iv_icon.setImageResource(images[position]);
//设置标题文字
viewHolder.tv_title.setText(names[position]);
//设置内容文字
viewHolder.tv_content.setText("我是" + names[position]);
//返回item的布局
return convertView;
}
class ViewHolder {
ImageView iv_icon;
TextView tv_title;
TextView tv_content;
}
}
}
让程序写入生命,将代码融入灵魂
-------smile、zj
相关文章推荐
- Android基本控件之ListView(二)<ListView优化>
- Android基本控件之listView(三)<用ListView实现分页加载>
- Android2.1--UI基本控件<1>--ListView
- Android2.1--UI基本控件<2>--Button
- Android2.1--UI基本控件<3>--初学者对Intent的理解
- <Android>控件Spinner的基本使用
- Android实战简易教程<五十一>(ListView实现子控件的动态显示和隐藏、checkbox全选和反选)
- android面试题目大全<第一部分>,android基本的UI控件和布局文件知识
- Android ListView控件基本用法以及范例
- Android ListView控件基本用法
- Android ListView控件基本用法 (转载)
- Android学习笔记:<二>03.Android当中的常用控件
- Android 控件<button>对齐方法
- 我的Android进阶之旅------>Android ListView优化详解
- 一步一步学android之控件篇——ListView基本使用
- 一步一步学android之控件篇——ListView基本使用
- 《ASP.NET1200例》ListView 控件与DataPager控件的结合<一>
- Android OpenGL ES 简明开发教程 03 <3D绘图基本概念>
- 【Android基本控件】ListView 的用法
- Android UI 优化 [ 类别:Layout ] <merge>的学习