前言
很多书籍都会讲到ListView的缓存优化,这个想必大家都知道。也正是因为缓存,让ListView变得有时候让人摸不着头脑。比如说我想做一个有圆角背景效果的ListView,如下图:
也许很多人都会想到在getView方法里,根据position去采用不同的圆角背景图片,如果仅仅是这样,你会发现结果出乎你的意料:为什么有些地方不该圆的它圆了,该圆的它不圆?其实这就是缓存机制导致的。当然了,你也可以选择不采用缓存,但是这会导致性能大大降低,当数据量比较大时,快速滑动列表就会出现比较明显的卡顿现象。本篇博客讲的方法是,既要保证性能,又能保证四个角落为圆角,其他地方不为圆角。
实现方法
在适配器里面,重写BaseAdapter中的getItemViewType(int position )和 getViewTypeCount( ) 这两个方法。告诉安卓系统框架当前的item是什么类型、总共有多少种类型的item。然后,在大家都很熟悉的getView方法里面,根据当前的viewType去加载不同的界面布局就可以了。
关键代码
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
int itemViewType = getItemViewType(i);
if (view==null){
if (itemViewType==BaseItem.TEXT){
view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.text_item,viewGroup,false);
TextViewHolder textViewHolder = new TextViewHolder();
textViewHolder.groupNameTv=view.findViewById(R.id.tv);
view.setTag(textViewHolder);
}else if (itemViewType==BaseItem.HERO1){
view=initView(viewGroup,R.layout.hero_item);
}else if (itemViewType==BaseItem.HERO2){
view=initView(viewGroup,R.layout.hero_item2);
}else if (itemViewType==BaseItem.HERO3){
view=initView(viewGroup,R.layout.hero_item3);
}else if (itemViewType==BaseItem.HERO4){
view=initView(viewGroup,R.layout.hero_item4);
}else {
view=new View(viewGroup.getContext());
}
}
Object tag = view.getTag();
BaseItem baseItem = list.get(i);
if (tag instanceof TextViewHolder){
TextViewHolder textViewHolder= (TextViewHolder) tag;
if (baseItem instanceof TextItem){
TextItem textItem= (TextItem) baseItem;
textViewHolder.groupNameTv.setText(textItem.getGroupName());
}
}else if(tag instanceof HeroViewHolder){
HeroViewHolder heroViewHolder= (HeroViewHolder) tag;
if ((baseItem instanceof HeroItem)){
HeroItem heroItem= (HeroItem) baseItem;
heroViewHolder.nameTv.setText(heroItem.getHeroName());
heroViewHolder.genderTv.setText(heroItem.getGender());
heroViewHolder.wordTv.setText(heroItem.getWord());
}
}
return view;
}
private View initView(ViewGroup viewGroup, int layout){
View view = LayoutInflater.from(viewGroup.getContext()).inflate(layout, viewGroup, false);
HeroViewHolder heroViewHolder=new HeroViewHolder();
heroViewHolder.nameTv= view.findViewById(R.id.nameTv);
heroViewHolder.genderTv= view.findViewById(R.id.genderTv);
heroViewHolder.wordTv= view.findViewById(R.id.wordTv);
view.setTag(heroViewHolder);
return view;
}
@Override
public int getItemViewType(int position) {
BaseItem baseItem = list.get(position);
int type=baseItem.getViewType();
if(BaseItem.TEXT==type){
return BaseItem.TEXT;
}else {
if(position<list.size()-1){//不是最后一项
BaseItem beforeItem = list.get(position - 1);
BaseItem afterItem = list.get(position + 1);
if (beforeItem.getViewType()==BaseItem.TEXT){
if (afterItem.getViewType()==BaseItem.TEXT){
return BaseItem.HERO1;//四个角都是圆的
}else {
return BaseItem.HERO2;//上面两个角是圆的
}
}else {
if(afterItem.getViewType()==BaseItem.TEXT){
return BaseItem.HERO3;//下面两个角是圆的
}else {
return BaseItem.HERO4;//没有一个角是圆的
}
}
}else {//最后一项
BaseItem beforeItem = list.get(position - 1);
if (beforeItem.getViewType()==BaseItem.TEXT){
return BaseItem.HERO1;
}else {
return BaseItem.HERO3;
}
}
}
}
@Override
public int getViewTypeCount() {
return 6;
}
public static class BaseItem{
public static final int TEXT=0;
public static final int HERO=1;
public static final int HERO1=2;//全圆角
public static final int HERO2=3;//上半圆角
public static final int HERO3=4;//下半圆角
public static final int HERO4=5;//无圆角
private int viewType;
public BaseItem(int viewType) {
this.viewType = viewType;
}
public int getViewType() {
return viewType;
}
public void setViewType(int viewType) {
this.viewType = viewType;
}
}
项目的地址
整个项目源码已经放到码云上了点我跳到码云