RecyclerView为什么会卡

RecyclerView作为v7包的新控件,自从推出就广受Android Developer们欢迎,实际上它已经取代了ListView和GridView两位老前辈的地位。然而不少亲们想必也已经发现了:没有优化过的Recycler性能很poor。上一篇博主使用的item也仅仅是一个图两串字而已,结果一滑动就卡的要命,不能忍!
那么why?回想在用ListView和GridView的adapter时,我们是用一种叫ViewHolder的自定义类(容器)来实现优化的,而RecyclerView的特性之一就是强制你使用它的RecyclerView.ViewHolder。可是,RecyclerView.ViewHolder要比我们写的那个单纯的容器复杂多了(源码里算上注释有大约500行),与RecyclerView.Adapter的联系也是千丝万缕。
按stackoverflow上面比较通俗的解释:RecyclerView.Adapter里面的onCreateViewHolder()方法和onBindViewHolder()方法对时间都非常敏感。类似I/O读写,Bitmap解码一类的耗时操作,最好不要在它们里面进行。
如何解决这个问题
首先当然得优化你的item,合理运用<include>,<merge>,<ViewStub>等标签,使布局层次尽量少——其实ListView和GridView里你也应该这么做,应该当成是一种写UI的习惯。
其次就是灵活使用各种第三方库,去完成各种耗时操作,比如通过Glide或者是Picasso加载图片。优秀的开源库在性能上往往都考虑得很仔细。
最后的问题来了,如果只想写一个小demo,不愿大张旗鼓怎么办?如果即便一般的第三方库也不好解决问题,比如上一篇那个该死的loadIcon()方法返回的是一个Drawable对象,Glide和Picasso都没法直接处理,转码又等于添了个耗时任务,那怎么办?
真正的app管理应用,应该引入UIL或者Picasso一类的加载库进行图标加载
答案就是,想法在你setAdapter之前就把任务给完成。
Demo
哟西,上代码!本文代码完全基于上一篇文,无须删减重构。
主要就是增添了一个实体bean对象,setAdapter()时要传递的数据,全部通过它预先加载到内存里!这样那俩敏感方法里只需要简单的get出来即可。
实体类AppBean.java
package com.example.jin.localapp;
import android.graphics.drawable.Drawable;
/**
* Created by Jin on 2016/11/8.
*/
public class AppBean {
private CharSequence name;
private String packageName;
private Drawable icon;
//这类代码可别逞英雄手动写哦,IDE(Android Studio和Eclipse都有的)里可以直接生成
public CharSequence getName() {
return name;
}
public void setName(CharSequence name) {
this.name = name;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public Drawable getIcon() {
return icon;
}
public void setIcon(Drawable icon) {
this.icon = icon;
}
}
主界面MainActivity.java
private List<AppBean> mList;//mList的泛型换成AppBean
private void initData() {//然后只需要改这个方法
mList = new ArrayList<>();
manager = getPackageManager();
List<PackageInfo> list = manager.getInstalledPackages(0);//获取已安装的全部应用
for (PackageInfo info : list) {
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
AppBean bean = new AppBean();
bean.setName(info.applicationInfo.loadLabel(manager));
bean.setPackageName(info.packageName);
bean.setIcon(info.applicationInfo.loadIcon(manager));
mList.add(bean);
}
}
//拿到数据再setAdapter
mainRcv.setLayoutManager(new LinearLayoutManager(this));
mainRcv.setHasFixedSize(true);
mainRcv.setAdapter(new AppAdapter(this, mList));
}
适配器AppAdapter.java
private List<AppBean> appList;
//同样这边的类型换过来
public AppAdapter(Context context, List<AppBean> appList) {
this.context = context;
this.appList = appList;
inflater = LayoutInflater.from(context);
manager = context.getPackageManager();
}
//然后也只需要改这个方法
@Override
public void onBindViewHolder(AppHolder holder, final int position) {
final AppBean bean = appList.get(position);
holder.itemIconIv.setImageDrawable(bean.getIcon());//图标
holder.itemNameTv.setText(bean.getName());//名称
holder.itemPackageTv.setText(bean.getPackageName());//包名
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(manager.getLaunchIntentForPackage(bean.getPackageName()));//根据包名启动此应用
context.startActivity(intent);
}
});
}
搞定!因为博主是用手机直接录像再转gif,为了使点击看上去有效果,于是给item增添了一个背景层,这需求实战中也是很常见的哦~~
色彩资源文件colors.xml
这个粉红色其实很难看,单纯当区别用。。。。。。
实战开发如果没有美工,一定要仔细斟酌选取,尽量让自己审美好点!
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <color name="colorWhite">#ffffff</color> <color name="colorPink">#f8bbd0</color> </resources>
选择器item_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@color/colorWhite" /> <item android:state_focused="true" android:drawable="@color/colorPink" /> <item android:state_pressed="true" android:drawable="@color/colorPink" /> <item android:drawable="@color/colorWhite"/> </selector>
条目布局item_app.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/item_selector" android:layout_width="match_parent" android:layout_height="60dp"> <!-- 中间内容无须修改,略--> </RelativeLayout>
最终运行效果
截图已经不太能感受到卡了,真机运行更加流畅!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# recyclerview卡顿
# recyclerview滑动卡顿
# recyclerview卡顿问题
# Android中使用RecyclerView实现下拉刷新和上拉加载
# Android中RecyclerView布局代替GridView实现类似支付宝的界面
# Android中RecyclerView实现多级折叠列表效果(二)
# Android中RecyclerView实现横向滑动代码
# Android RecyclerView网格布局(支持多种分割线)详解(2)
# Android Recyclerview实现多选
# 单选
# 全选
# 反选
# 批量删除的功能
# Android RecyclerView 复用错乱通用解法详解
# Android RecyclerView实现下拉刷新和上拉加载
# Android项目实战之仿网易新闻的页面(RecyclerView )
# Android如何利用RecyclerView实现列表倒计时效果实例代码
# 只需要
# 上一篇
# 加载
# 机运
# 第三方
# 的是
# 是一个
# 逞英雄
# 来了
# 是一种
# 不太
# 你也
# 增添了
# 不愿
# 两位
# 这类
# 就把
# 得很
# 用手
# 千丝万缕
相关文章:
孙琪峥织梦建站教程如何优化数据库安全?
如何高效完成自助建站业务培训?
小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化
微信小程序 五星评分(包括半颗星评分)实例代码
如何零成本快速生成个人自助网站?
如何通过wdcp面板快速创建网站?
建站之星代理商如何保障技术支持与售后服务?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
网站制作壁纸教程视频,电脑壁纸网站?
定制建站流程解析:需求评估与SEO优化功能开发指南
黑客如何利用漏洞与弱口令入侵网站服务器?
阿里云网站制作公司,阿里云快速搭建网站好用吗?
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
建站主机核心功能解析:服务器选择与网站搭建流程指南
做企业网站制作流程,企业网站制作基本流程有哪些?
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
如何在万网主机上快速搭建网站?
宝塔建站后网页无法访问如何解决?
nginx修改上传文件大小限制的方法
,网页ppt怎么弄成自己的ppt?
临沂网站制作公司有哪些,临沂第四中学官网?
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
如何快速搭建自助建站会员专属系统?
网站建设制作、微信公众号,公明人民医院怎么在网上预约?
如何快速查询域名建站关键信息?
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
网站制作网站,深圳做网站哪家比较好?
成都响应式网站开发,dw怎么把手机适应页面变成网页?
如何在IIS管理器中快速创建并配置网站?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
如何在阿里云ECS服务器部署织梦CMS网站?
视频网站app制作软件,有什么好的视频聊天网站或者软件?
如何零基础开发自助建站系统?完整教程解析
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
网站制作公司,橙子建站是合法的吗?
专业公司网站制作公司,用什么语言做企业网站比较好?
如何快速登录WAP自助建站平台?
定制建站如何定义?其核心优势是什么?
如何安全更换建站之星模板并保留数据?
宝塔Windows建站如何避免显示默认IIS页面?
香港服务器部署网站为何提示未备案?
巅云智能建站系统:可视化拖拽+多端适配+免费模板一键生成
枣阳网站制作,阳新火车站打的到仙岛湖多少钱?
如何通过二级域名建站提升品牌影响力?
宝塔新建站点为何无法访问?如何排查?
常州企业建站如何选择最佳模板?
名字制作网站免费,所有小说网站的名字?
Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递
大学网站设计制作软件有哪些,如何将网站制作成自己app?
*请认真填写需求信息,我们会在24小时内与您取得联系。