Comments (7)
可以把它优化没了,不使用不就好了
from android-daily-interview.
不邀自来,这个问题很有深度,但是建议直接使用RecyclerView
再次建议使用RecyclerView
下面是优化建议:
怎样最大化的优化ListView的性能?
- 1.在adapter中的getView方法中尽量少使用逻辑
- 2.尽最大可能避免GC
- 3.滑动的时候不载入图片
- 4.将ListView的scrollingCache和animateCache设置为false
- 5.item的布局层级越少越好
- 6.使用ViewHolder
1.在adapter中的getView方法中尽量少使用逻辑
不要在你的getView()中写过多的逻辑代码,我们能够将这些代码放在别的地方。比如:
优化前的getView():
@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
Object current_event = mObjects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_event, null);
holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//在这里进行逻辑推断。这是有问题的
if (doesSomeComplexChecking()) {
holder.ThreeDimention.setVisibility(View.VISIBLE);
} else {
holder.ThreeDimention.setVisibility(View.GONE);
}
// 这是设置image的參数,每次getView方法运行时都会运行这段代码。这显然是有问题的
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
holder.EventPoster.setLayoutParams(imageParams);
return convertView;
}
优化后的getView():
@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
Object object = mObjects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_event, null);
holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
//设置參数提到这里,仅仅有第一次的时候会运行,之后会复用
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
holder.EventPoster.setLayoutParams(imageParams);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 我们直接通过对象的getter方法取代刚才那些逻辑推断。那些逻辑推断放到别的地方去运行了
holder.ThreeDimension.setVisibility(object.getVisibility());
return convertView;
}
2.GC 垃圾回收器
当你创建了大量的对象的时候。GC就会频繁的运行。所以在getView()方法中不要创建非常多的对象。最好的优化是,不要在ViewHolder以外创建不论什么对象。假设你的你的log里面发现“GC has freed some memory”频繁出现的话。那你的程序肯定有问题了。
你能够检查一下:
a) item布局的层级是否太深
b) getView()方法中是否有大量对象存在
c) ListView的布局属性
3.载入图片
假设你的ListView中须要显示从网络上下载的图片的话。我们不要在ListView滑动的时候载入图片,那样会使ListView变得卡顿,所以我们须要再监听器里面监听ListView的状态。假设滑动的时候,停止载入图片,假设没有滑动,则開始载入图片
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView listView, int scrollState) {
//停止载入图片
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
imageLoader.stopProcessingQueue();
} else {
//開始载入图片
imageLoader.startProcessingQueue();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
4.将ListView的scrollingCache和animateCache设置为false
scrollingCache: scrollingCache本质上是drawing cache,你能够让一个View将他自己的drawing保存在cache中(保存为一个bitmap),这样下次再显示View的时候就不用重画了,而是从cache中取出。默认情况下drawing cahce是禁用的。由于它太耗内存了,可是它确实比重画来的更加平滑。
而在ListView中,scrollingCache是默认开启的,我们能够手动将它关闭。
animateCache: ListView默认开启了animateCache,这会消耗大量的内存,因此会频繁调用GC,我们能够手动将它关闭掉
优化前的ListView
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#00000000"
android:divider="@color/list_background_color"
android:dividerHeight="0dp"
android:listSelector="#00000000"
android:smoothScrollbar="true"
android:visibility="gone" />
优化后的ListView
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/list_background_color"
android:dividerHeight="0dp"
android:listSelector="#00000000"
android:scrollingCache="false"
android:animationCache="false"
android:smoothScrollbar="true"
android:visibility="gone" />
5.降低item的布局的深度
我们应该尽量降低item布局深度,由于当滑动ListView的时候,这回直接导致測量与绘制,因此会浪费大量的时间。所以我们应该将一些不必要的布局嵌套关系去掉。降低item布局深度
6.使用ViewHolder
这个大家应该非常熟悉了,可是不要小看这个ViewHolder,它能够大大提高我们ListView的性能
再次建议使用RecyclerView
from android-daily-interview.
emmm....用 RecyclerView 替换 ListView
from android-daily-interview.
菜鸡也来说说
1.数据处理 即vh无压力进行数据与视图的绑定,而不用再处理数据(比如我们需要赋值的是省市名称,列表里是行政区划,这种转换操作就不要放在adapter内操作了)
2.局部刷新 (即使用RecyclerView代替listview,可使用DiffUtil来实现局部刷新,提高性能)
3.布局优化 (即减少view的绘制)
3.1 减少布局的嵌套 (合理使用布局、自定义view)
3.2 减少 xml 文件 inflate 时间(xml 文件 inflate 出 ItemView 是通过耗时的 IO 操作,当itemView的复用率低,可以考虑使用代码去生成布局,即 new View() 的方式,只要搞清楚 xml 中每个节点的属性对应的 API 即可)
3.3减少view对象的创建 (尽可能简化itemview,减少其的构造和嵌套)
4.关于TextView
4.1对 TextView 使用 String.toUpperCase 来替代 android:textAllCaps="true"。
4.2对 TextView 使用 StaticLayout 或者 DynamicLayout 的自定义 View 来代替它。
5.对 ItemView 设置监听器,不要对每个 Item 都调用 addXxListener,应该大家公用一个 XxListener,根据 ID 来进行不同的操作,优化了对象的频繁创建带来的资源消耗。
沐风大佬 我是小黑 QAQ
from android-daily-interview.
2楼正解
from android-daily-interview.
ViewHolder什么的持有View
预加载/懒加载数据什么的
大招:用RecyclerView替换ListView
绝招:直接删除控件
from android-daily-interview.
不邀自来,这个问题很有深度,但是建议直接使用RecyclerView
再次建议使用RecyclerView
下面是优化建议:
怎样最大化的优化ListView的性能?
- 1.在adapter中的getView方法中尽量少使用逻辑
- 2.尽最大可能避免GC
- 3.滑动的时候不载入图片
- 4.将ListView的scrollingCache和animateCache设置为false
- 5.item的布局层级越少越好
- 6.使用ViewHolder
1.在adapter中的getView方法中尽量少使用逻辑
不要在你的getView()中写过多的逻辑代码,我们能够将这些代码放在别的地方。比如:
优化前的getView():
@Override public View getView(int position, View convertView, ViewGroup paramViewGroup) { Object current_event = mObjects.get(position); ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = inflater.inflate(R.layout.row_event, null); holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim); holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } //在这里进行逻辑推断。这是有问题的 if (doesSomeComplexChecking()) { holder.ThreeDimention.setVisibility(View.VISIBLE); } else { holder.ThreeDimention.setVisibility(View.GONE); } // 这是设置image的參数,每次getView方法运行时都会运行这段代码。这显然是有问题的 RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight); holder.EventPoster.setLayoutParams(imageParams); return convertView; }优化后的getView():
@Override public View getView(int position, View convertView, ViewGroup paramViewGroup) { Object object = mObjects.get(position); ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = inflater.inflate(R.layout.row_event, null); holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim); holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster); //设置參数提到这里,仅仅有第一次的时候会运行,之后会复用 RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight); holder.EventPoster.setLayoutParams(imageParams); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 我们直接通过对象的getter方法取代刚才那些逻辑推断。那些逻辑推断放到别的地方去运行了 holder.ThreeDimension.setVisibility(object.getVisibility()); return convertView; }2.GC 垃圾回收器
当你创建了大量的对象的时候。GC就会频繁的运行。所以在getView()方法中不要创建非常多的对象。最好的优化是,不要在ViewHolder以外创建不论什么对象。假设你的你的log里面发现“GC has freed some memory”频繁出现的话。那你的程序肯定有问题了。
你能够检查一下:
a) item布局的层级是否太深
b) getView()方法中是否有大量对象存在
c) ListView的布局属性3.载入图片
假设你的ListView中须要显示从网络上下载的图片的话。我们不要在ListView滑动的时候载入图片,那样会使ListView变得卡顿,所以我们须要再监听器里面监听ListView的状态。假设滑动的时候,停止载入图片,假设没有滑动,则開始载入图片
listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView listView, int scrollState) { //停止载入图片 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) { imageLoader.stopProcessingQueue(); } else { //開始载入图片 imageLoader.startProcessingQueue(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub } });4.将ListView的scrollingCache和animateCache设置为false
scrollingCache: scrollingCache本质上是drawing cache,你能够让一个View将他自己的drawing保存在cache中(保存为一个bitmap),这样下次再显示View的时候就不用重画了,而是从cache中取出。默认情况下drawing cahce是禁用的。由于它太耗内存了,可是它确实比重画来的更加平滑。
而在ListView中,scrollingCache是默认开启的,我们能够手动将它关闭。
animateCache: ListView默认开启了animateCache,这会消耗大量的内存,因此会频繁调用GC,我们能够手动将它关闭掉
优化前的ListView
<ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:cacheColorHint="#00000000" android:divider="@color/list_background_color" android:dividerHeight="0dp" android:listSelector="#00000000" android:smoothScrollbar="true" android:visibility="gone" />
优化后的ListView
<ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@color/list_background_color" android:dividerHeight="0dp" android:listSelector="#00000000" android:scrollingCache="false" android:animationCache="false" android:smoothScrollbar="true" android:visibility="gone" />
5.降低item的布局的深度
我们应该尽量降低item布局深度,由于当滑动ListView的时候,这回直接导致測量与绘制,因此会浪费大量的时间。所以我们应该将一些不必要的布局嵌套关系去掉。降低item布局深度
6.使用ViewHolder
这个大家应该非常熟悉了,可是不要小看这个ViewHolder,它能够大大提高我们ListView的性能
再次建议使用RecyclerView
阿明这两天好勤快
from android-daily-interview.
Related Issues (20)
- 2020-01-14:为什么协程比线程要轻量? HOT 19
- 2020-01-15:你了解过哪些Android屏幕适配方面的技巧? HOT 2
- 2020-01-16:为什么ViewPager嵌套ViewPager,内部的ViewPager滚动没有被拦截? HOT 3
- 2020-01-17:说说你未来的职业规划是怎样的? HOT 23
- 2020-03-02:Java中为什么会出现Atomic类?试分析它的原理和缺点? HOT 1
- 2020-03-03:说说ThreadLocal的使用场景?与Synchronized相比有什么特性? HOT 6
- 2020-03-04:试从源码角度分析Handler的post和sendMessage方法的区别和应用场景? HOT 6
- 2020-03-06:JMM是什么?它存在哪些问题?该如何解决? HOT 3
- 2020-03-09:谈谈Https的加密过程? HOT 3
- 113 Android Interview Questions Answered (ENGLISH) HOT 1
- 当点击的时候,会先调用顶级viewgroup的dispatchTouchEvent,如果顶级的viewgroup拦截了此事件(onInterceptTouchEvent返回true),则此事件序列由顶级viewgroup处理。如果顶级viewgroup设置setOnTouchListener,则会回调接口中的onTouch,此时顶级的viewgroup中的onTouchEvent不再回调,如果不设置setOnTouchListener则onTouchEvent会回调。如果顶级viewgroup设置setOnClickListener,则会回调接口中的onClick。如果顶级viewgroup不拦截事件,事件就会向下传递给他的子view,然后子view就会调用它的dispatchTouchEvent方法。
- 2020-9-29:Java内存模型 HOT 1
- 2020-9-29:java中的锁机制
- app 进程分为哪几种?在项目中的实际应用?
- 学习
- View inflation
- 群被封了 HOT 2
- Android HOT 2
- 为啥不搞了 HOT 3
- 2024年了, Android行情怎么样了 HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from android-daily-interview.