起因
鉴于最近有一个岗位晋升考核,并且自己一路走来的一些知识点没有进行过积累,也就借此机会,在这里简单的做一下纪录,当作备忘。
视图渲染效果差(卡顿)的原因分析
人的眼睛具有“视觉暂留”特性,就是人的眼睛看到一幅画面或一个物体后,在1/24秒内不会消失,利用这一视觉变化效果。因此电影采用了每秒24幅画的速度拍摄播放,电视采用了每秒25幅(PAL制)或30幅(NSTC制)画面的速度拍摄播放,如果以每秒低于24幅画面的速度拍摄播放,就会出现停顿现象。 app中试图渲染绘制是在ui现场中进行,当我们的操作导致ui线程耗时较长的话,就会导致ui卡顿。这里按照自己的经验,汇总几种导致ui绘制卡顿的问题点:
1、布局文件中层级之间的控件大小不明确,导致过度的重复计算。
2、布局文件中层级太深。eg:布局最终显示占的大小,如果不明确制定的话,是根据子view进行计算获取,
每个子view的大小确定之后,才会逐层向上确定最后的显示大小,当层级很深的话,会造成大量的计算操作。
3、在ui线程中进行了大量的计算。eg:这个不用解释,做android的都懂
4、ui刷新太频繁。eg:例如在下载操作中,频繁的发送ui更新操作
listview优化
1、使用ViewHolder进行优化,优化原理其实就是做到视图复用。做android的都懂。不解释。
2、尽可能的不去在getview中做耗时操作,getview这块,从设计之初,就是只是为了视图展示而生的,
在这里做大量计算,铁定卡。所以,如果非在这里要进行大量逻辑计算的话,请砍死自己或者去砍死产品吧。
3、如果有后台线程在刷新ui的话,控制好刷新的速率,刷新太快的话,会造成ui渲染频繁,导致ui卡顿。
4、对于一些并非需要刷新整个ui的操作,尽可能做到单个ui刷新,不要让整个可见视图整体做视图渲染。
5、ui布局上面,布局大小明确,不要每次都去计算宽高度。布局层级不要太深。
6、使用自定义布局,去替代重复的linearlayout布局。这样操作也是降低层级。
listview刷新单个item的方法
方法一
private void updateView(Listview mlistview, int itemIndex){
int fristVisiblePosition = mlistview.getFirstVisblePosition();
View v = mlistview.getChildAt(itemIndex - fristVisiblePosition);
ViewHolder ViewHolder = (ViewHolder)v.getTag();
if(viewHolder != null){
viewHolder.titleTextView.setText("更新了");
}
}
方法二
private void updateView(listview mlistview, Data data){
if(mlistview != null){
int start = mlistview.getFirstVisblePosition();
int end = mlistview.getLastVisiblePosition();
for(int i=start, i <= end;i++){
Data temp = (Data)mlistview.getItemAtPosition();
if(temp == data){
View view = mlistview.getChildAt(i - start);
getView(i, view, mlistview);
}
}
}
}