上一篇博文讲到了ListView创建以及使用方法,接下来我为大家介绍关于ListView的优化以及数据封装。对于一个好的程序员来说,不仅仅要考虑到程序的运行无误,也要考虑到程序的性能。要考虑大程序以后用户量大或者数据多的时候怎么样合理使用安卓提供给我的优化方法优化程序,使得程序即使有许多人在用也不至于崩溃或异常。
如果大家对我的博文有什么意见或者有什么疑问可以给我留言我会尽所能的修改博文以及回答问题,由于本博客是基于上一篇博文写的所以一些重复的内容我就省略,这是上一篇博文的链接 http://7735447.blog.51cto.com/blog/7725447/1270533
1:getView()方法的参数介绍。
(1):在Adpter适配器的getView()方法中有3个参数
@Override public View getView(int position, View convertView, ViewGroup parent) { Log.e("getView()", "position"+position); View layout = getLayoutInflater().inflate(R.layout.list, null); return layout; }
position表示的是系统运行到的行布局的位置(例如第一个行布局的position为0,第二个为1,以此类推),系统会首先运行屏幕所能看到的最多行布局的次数(例如屏幕只能看到7个行布局,系统就会运行7次getView()方法,然后每次postion值从0递增到6,类型for循环的i)。如下图的日志
当用户下拉或者上啦的时候系统会继续运行getView()方法来显示接下来的行布局
(2):第二个参数ConverView为复用的行布局。大家想想,如果我们listView的行布局有100个,那就要在内存中创建100个行布局对象,如果更多呢。内存的消耗就会越来越大。于是这里getView()为我们传来一个复用的行布局,当用户下拉时候,最上面的行布局对象变为ConverView来给我们下拉后看到第一个行布局使用(向上拉同理),这样以来系统只会创建一个屏幕最多能显示的行布局对象,向下拉复用第一个行布局对象,向上拉复用屏幕最下角的对象。无论在多的行布局都没关系,这样就完成了
对内存的优化。根据这样原理我们来改写下代码,当ConverView为空时候创建行布局对象然后return,当复用的时候(即ConverView不为空的时候),就让布局对象的引用等于ConverView。具体代码如下
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//Log.e("getView()", "position"+position);
View layout = null;
ViewHolder holder;
if(convertView == null)
{
layout = getLayoutInflater().inflate(R.layout.list, null);
holder = new ViewHolder();
holder.mImage = (ImageView) layout.findViewById(R.id.p_w_picpathView1);
holder.mTitle = (TextView) layout.findViewById(R.id.textView1);
holder.mSubtitle = (TextView) layout.findViewById(R.id.textView2);
layout.setTag(holder);
}
else
{
layout = convertView;
holder = (ViewHolder) layout.getTag();
}
return layout;
}
2:行布局的控件封装(ViewHolder)
(1):在上面条件语句后我们获得layout对象,接下来我们来获得行布局所有控件的对象(这里注意一定要用布局对象的findViewById()方法,不能像ACTIVITY的findViewById()方法省略自身引用,否则会引起空指针异常)具体代码如下
ImageView p_w_picpath = (ImageView) layout.findViewById(R.id.p_w_picpathView1);
TextView title = (TextView) layout.findViewById(R.id.textView1);
TextView subtitle = (TextView) layout.findViewById(R.id.textView2);
然后这里出现了一个问题,当我们每次运行getView()方法时候我们都要去找到行布局里的控件对象。复用的时候也要去找,这又是一个相当消耗资源的运行方式。基于这个问题我们可以创建一个内部类ViewHolder(类名随便取),然后将找到的所有行布局里面控件的对象封装在这个类里,调用布局对象的setTag()方法将这个类带在Layout对象的身边,等到复用时候在调用getTag()方法将其取出来,这样我们实际上只找了屏幕能看见最大行布局数量的次数。解决的资源消耗的问题 具体代码如下
class ViewHolder { ImageView mImage; TextView mTitle; TextView mSubtitle; }
3:数据封装(ItemData)
(1):我们封装完了行布局的所有控件对象,接下来就开始封装屏幕要显示的数据,首先我们来写个类
ItemData用来封装。
class Itemdata { private String title; private String subtitle; private int p_w_picpath; public Itemdata(String title, String subtitle, int p_w_picpath) { super(); this.title = title; this.subtitle = subtitle; this.p_w_picpath = p_w_picpath; } }
然后定义个容器来装ItemData对象,定义个数组来装图片所需要的r文件
private ArrayList<Itemdata> mData = new ArrayList<Itemdata>(); int[] a = new int[]{R.drawable.a0,R.drawable.a1,R.drawable.a2,R.drawable.a3, R.drawable.a4,R.drawable.a5,R.drawable.a6,R.drawable.a7, R.drawable.a8,R.drawable.a9,};
写个for循环将每一行的行布局的数据的对象装进容器中
for (int i = 0; i < 10; i++) { Itemdata itemdata = new Itemdata("title"+i,"subtitle"+i,a[i]); mData.add(itemdata); }
最后在getView分别调用各自控件的方法将数据传入行布局内
Itemdata itemdata = mData.get(position); holder.mImage.setImageResource(itemdata.p_w_picpath); holder.mTitle.setText(itemdata.title); holder.mSubtitle.setText(itemdata.subtitle);
打工告成,显示结果如下
4:这就是listview控件优化和数据封装,我会吧整个程序打包如果有需要的话可以拿去看看.下次博客介绍常用的2个适配器类SimpleAdapter以及ArrayAdapter。(未完待续。。。。。)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。