本文地址:http://blog.csdn.net/mba16c35/article/details/43707407
使用适当的开源库,如Volley或者Universal ImageLoader
public class MyImageLoader extends ImageLoader {
/**
* 每个activity把自己的context作为参数生成imageloader,保证每个requestqueue是属于activity的
* 退出activity后所有request都取消掉
* @param ct
*/
public MyImageLoader(Context ct) {
super(MyRequestQueue.newInstance(ct), MyImageCache.getInstance());
}
public void stopProcessingQueue() {
getRequestQueue().stop();
}
public void startProcessingQueue() {
getRequestQueue().start();
}
}
另外也同样可以在Adapter中设置标志位,表示是否正在快速滑动,如果正在快速滑动,Adapter中的getView只需要把TextView等简单数据显示出来,把复杂逻辑和onClickListener等移到非Fling状态时才设置。
关于Volley的介绍可以看这篇博客:http://blog.csdn.net/t12x3456/article/details/9221611
关于Volley的源码分析可以看我的博客:http://blog.csdn.net/mba16c35/article/details/43944703
采用扁平化的布局
层层嵌套的布局会花费很多渲染时间。
使用merge标签
一个常见的不需要嵌套的例子是使用FrameLayout作为布局的单一根节点,当该布局被添加到一个父容器时,它就会成为冗余。更好的做法是使用merge标签。当包含有merge标签的布局被添加到另一个布局时,该布局的merge节点会被删除,而该布局的子View会被直接添加到新的父布局中。
mege标签结合include标签一起使用可以复用布局同时,减少嵌套
include标签可以把一个布局的内容插入到另一个布局。利用include标签可以在垂直和水平方向的不同布局中共享大多数UI布局。
延迟加载
View Stub是一个可见的、大小为0的View,它就像一个延迟填充的include标签,只有在显示调用inflate方法或者被置为可见是,这个stub才被填充。
更多详解介绍可以参考:《Android4高级编程》P90,《Android优化技术详解》P76
注意Adapter的getView函数的编写
(1)复用convertView。convertView是ListView的RecycleBin内部类帮我们缓存的,如果ListView的不同列表项有不同的类型,可以在Apdater的getViewTypeCount中返回类型数,ListView会根据不同类别分别缓存。可以看我之前对ListView源代码的分析:http://blog.csdn.net/mba16c35/article/details/43638793
(2)使用静态内部类ViewHolder。新建列表项视图的各项子视图都存在ViewHolder中,然后setTag,下次直接通过
ItemViewHolder holder = (ItemViewHolder) convertView.getTag();
就省去了findViewById的步骤。
下面是一段示例代码。XXNetworkImageView继承Volley中的NetworkImageView。
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView==null)
{
convertView = mInflater.inflate(layoutID, null);
ItemViewHolder holder = new ItemViewHolder();
holder.bookCover = (XXNetworkImageView) convertView.findViewById(R.id.book_booklist_cover);
holder.bookName = (TextView) convertView.findViewById(R.id.book_booklist_name);
holder.bookClickNumber = (TextView) convertView.findViewById(R.id.book_booklist_clicknumber);
holder.bookType = (TextView) convertView.findViewById(R.id.book_booklist_type);
holder.bookAuthor = (TextView) convertView.findViewById(R.id.book_booklist_author);
holder.bookState = (ImageView) convertView.findViewById(R.id.book_booklist_state);
convertView.setTag(holder);
}
bindView(convertView, position);
return convertView;
}
private void bindView(View convertView, int position) {
ItemViewHolder holder = (ItemViewHolder) convertView.getTag();
String imageUrl = (String) Util.IMG_URL_PREFIX + bookList.get(position).getImgUrl();
String currentUrl = holder.bookCover.getUrl();
if (currentUrl == null || !currentUrl.equals(imageUrl)) {
if (mContext != null) {
holder.bookCover.setImageUrl(imageUrl, imageLoader, Util.dip2px(mContext, 95));
} else {
holder.bookCover.setImageUrl(imageUrl, imageLoader);
}
}
holder.bookName.setText(String.valueOf(bookList.get(position).getName()));
holder.bookClickNumber.setText(String.valueOf(bookList.get(position).getFreePage()));
holder.bookType.setText("类型: "+ String.valueOf(bookList.get(position).getTypes()));
holder.bookAuthor.setText("作者: " + String.valueOf(bookList.get(position).getAuthor()));
if(String.valueOf(bookList.get(position).getScale()).equals("0"))
holder.bookState.setImageResource(R.drawable.tag0);
// else if(String.valueOf(bookListData.get(position).get("state")).equals("1"))
// holder.bookState.setImageResource(R.drawable.tag);
}
static class ItemViewHolder {
XXNetworkImageView bookCover;
TextView bookName;
TextView bookClickNumber;
TextView bookType;
TextView bookAuthor;
ImageView bookState;
}