Listview的holder优化
1.细节边边角角都注意到(每个细节的优化,飞跃的进步)
服务器集群优化
服务器主板的USB口 5V 全部都给禁用
listVIew的优化
1.复用已经存在View对象,使用convertView,使用历史缓存view对象,减少view对象被创建的次数
2.holder,减少子孩子查询的次数
view.findViewById(),查找子孩子的逻辑:
在根布局里面还有很多别的子布局,在子布局里面还有很多子孩子控件。一般的view.inflate获得的都是root节点->view。在使用view.findViewById(R.id.textview03)的时候,下图可以看出是树状结构,在findViewById的时候会使用迭代,遍历所有的子布局中的子孩子控件,直到找到所需要的控件为止,如果结构逻辑较为复杂,就比较耗费时间
设置每个控件的特点(ID),通过ID,然后用findViewById()来找到对应的子控件,根据ID给每个子控件进行编号(设置Tag).ViewHolder可以理解为家庭组(view对象的容器),
ViewHoder holder=new ViewHolder();
//在父布局被创建的时候子控件就已经被找到了,并放到家庭组里
holder.tv_phone=(Textview)view.findViewById(R.id.tv_item_phone);
//设置一个标记(标签),把孩子id的引用存放到holder里面,设置给父亲view
view.setTag(holder);
那以后在复用缓存的view对象的时候,使用view.getTag();就可以将tag获取出来
理解:在父亲view在被创建出来的时候,holder家庭组(花名册)holder也存在的,这时候将孩子也找到,将找到的孩子id放入holder家庭组里面,在将家庭组设置给父亲View,在复用缓存的view对象的时候,就不在通过findViewById来遍历查找,直接通过tag标签获取到holder家庭组,直接在组里查找对应的孩子控件就可以了
父类中的构造函数,子类谁继承父类,那父类构造函数中的对象就是子类中自己的对象.不同的子类就有自己对应的对象
//家庭组,view对象的容器
class Viewholder{
TextViewtv_phone;
Textviewtv_number;
}
public void getView(int position, ViewconverView,ViewGroup parent){
Viewview;
ViewHolderholder;
if(convertView==null){
view=View.inflate(MianActivity.this,R.layout.item_classms,null);
holder.tv_phone=View.findViewbyid…
holder.tv_number=View.findViewById…..
view.setTag(holder);
}else{
view=converView;
holder=(ViewHolder)view.getTag();
}
holder的抽取:
判断convertView是否为空
为空
创建convertView:xml-->View(initView)
创建ViewHolder,viewholder
给convertView设置tag,tag就是创建出来的viewholder
convertView.findViewById()一系列操作(当用到的时候再去具体的子类中操作)
不为空
holder=convertView.getTag();
给控件设置数据
//当前展示条目的界面效果
return convertView
创建一个对象,调用构造方法,在调用构造方法的同时在一起调用initView(),这两个方法就绑定哎viewholder的构造方法里完成
声明一个BaseHoder类
构造方法中,
1.调用view=initView();但initView()会根据不同的继承者来进行具体的操作,所以,initView()只能抽象
2.要给当前的converView设置一个holder的tag,拿到view设置tag. view.setTag(this);
给控件设置数据的操作setData(),不同的listVIew对应的数据泛型都不一样,数据类型定不下来,只能用T
setData(T mData){
this.mData=mData;
//数据设置到控件上的方法
refreshView();//控件有什么未知,数据什么类型也未知,这个方法不能实现(抽象)
}
getRootView(){
return view;
}
具体实现:
publicabstract class BaseHolder<T>{
private View view;
private T mData;
public BaseHolder(){
//1.调用view=initView();
view=initView();
//2.给view设置tag
view.setTag(this);
}
public abstract View initView();
//给listView对应的每一个的条目设置数据的方法
public setData(T mData){
//传入的数据不管是什么,都要做对应的接收
this.mData=mData;
//数据设置到控件上的方法
refreshView();
}
public T getData(){
return mData;
}
public abstract void refreshView();
public view getRootView(){return view;}
在MyBaseAdapter里面进行设置
public voidgetView(int position, View converView,ViewGroup parent){
if(converView==null){
//不知道子类如何处理holder
BaseHolderholder=getHolder();
}else {
if(convertView.getTag()!=null){
holder=(BaseHolder) convertView.getTag();
}
}
//给控件设置数据
holder.setData(list.get(position));
returnholder.getRootView();
}
publicabstract BaseHolder getHolder();
在homeFragment的MyAdapter中
//当前listView对应的一般条目的holder
publicBaseHolder getHolder(){
returnnew HomeHolder();
}
在HomeHolder()extends BaseHolder中
public ViewinitView(){
view= UIUtils.inflate(R.layout.item_textview);
returnview;
}
public voidrefreshView(){
Stringdata=getData()’
//具体的数据,放置到具体的控件上面的操作
textViewtextview=view.findViewById(R.id.tv);
textview.setText(data);
}