接着前面的ListView简单应用(一)我们现在来谈谈ListView的优化问题。ListView的优化也是面试官经常会问到的问题,所以我们要重视。首先我们先了解一下为什么要进行ListView的优化?从我们上一章的代码中我们是很容易看出一个很消耗内存的问题,就是当我们每次打开这个ListView的时候我们总是要重新绘制一次这个VIew,这样非常的消耗内存而且也很不利于页面的加载导致用户体验非常的差,所以我们为了节省内存也为了使用户体验变好就必须进行ListView的优化了。
相信很多人接下来都会有一个问题:我们要怎么样才能优化ListView呢?其实上面就说的很明白了,我们ListView为什么耗内存啊?就是因为我们每次进入ListView都会重新绘制一遍它,所以这就是问题的关键了。我们有没有办法在第一次进入List VIew的时候把这个View存储起来然后等再次进入的时候读取出来,这样不就可以解决这个问题了么?办法已经找到了,接下我们就要用代码去实现,在getView()这个方法中有个参数convertView就是用来存储View。
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
myBean myBean = (myBean) getItem(position);
View view;//先声明一个View
if (convertView == null){//当concertView为空的时候才绘制一个View
view = LayoutInflater.from(getContext()).inflate(ImageId,parent,false);//这个是实例化一个我们自己写的界面Item
}else{
view =convertView;//当concertView不为空的时候在这里取出存储的View
}
LinearLayout linearLayout = view.findViewById(R.id.ll_view);
ImageView headImage = view.findViewById(R.id.headimage);
TextView headText = view.findViewById(R.id.headtext);
RadioGroup radio = view.findViewById(R.id.radioBtn);
headImage.setImageResource(myBean.getImageID());
headText.setText(myBean.getText());
radio.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {//检查Radio Button那个被点击了
@Override
public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
switch (i){
case R.id.radio1:
radiotext = "不打";
break;
case R.id.radio2:
radiotext = "打他";
break;
}
}
});
linearLayout.setOnClickListener(new View.OnClickListener() {//检查哪一项被点击了
@Override
public void onClick(View view) {
Toast.makeText(getContext(),"你点击了第"+position+"项"+"你选择"+radiotext,Toast.LENGTH_SHORT).show();
}
});
return view;
}
这样我们的问题就解决了,但是我们的ListView存在另外一个消耗内存的问题,作为强迫症的我是绝对不允许的。那就是我们每次进入LIstView里都得findViewById,这个也会耗损内存。我们有没有什么办法能把这些个控件也存储起来呢?这就是大家都有所听闻的ViewHolder。原理很简单就是创建一个静态类,然后把对底下的控件引用存在静态类里面,再在View.setTag(holder)把它放在view里,因为Tag存储的是标签信息,所以可以是任何内容,要把它和ID区分开呢!等到下次就可以直接取用。上个代码:
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder viewHolder;
myBean myBean = (myBean) getItem(position);
View view;//先声明一个View
if (convertView == null){//当concertView为空的时候才绘制一个View
viewHolder = new ViewHolder();
view = LayoutInflater.from(getContext()).inflate(ImageId,parent,false);//这个是实例化一个我们自己写的界面Item
viewHolder.fruitImage = view.findViewById(R.id.headimage);
viewHolder.fruitName = view.findViewById(R.id.headtext);
viewHolder.fruitLayout = view.findViewById(R.id.ll_view);
viewHolder.fruitRadio = view.findViewById(R.id.radioBtn);
view.setTag(viewHolder);//为空时把新内容存放在Tag里
}else{//当concertView不为空的时候在这里取出存储的View
view =convertView;
viewHolder = (ViewHolder)view.getTag();//不为空时把Tag的内容取出来
}
viewHolder.fruitImage.setImageResource(myBean.getImageID());
viewHolder.fruitName.setText(myBean.getText());
viewHolder.fruitRadio.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {//检查Radio Button那个被点击了
@Override
public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
switch (i){
case R.id.radio1:
radiotext = "不打";
break;
case R.id.radio2:
radiotext = "打他";
break;
}
}
});
viewHolder.fruitLayout.setOnClickListener(new View.OnClickListener() {//检查哪一项被点击了
@Override
public void onClick(View view) {
Toast.makeText(getContext(),"你点击了第"+position+"项"+"你选择"+radiotext,Toast.LENGTH_SHORT).show();
}
});
return view;
}
class ViewHolder{//用来存放控件的静态类
ImageView fruitImage;
TextView fruitName;
LinearLayout fruitLayout;
RadioGroup fruitRadio;
}
这样我们的ListView的优化之旅就告一段落了,可能还能更好的优化ListView的方法,有兴趣的大家留言探讨一下哈。
原创链接:https://blog.csdn.net/weixin_40600325/article/details/80817720