RecyclerViewAndroid精选Android知识

Android RecyclerView的卡顿问题

2016-11-08  本文已影响0人  彼岸sakura

本文其实是上一篇Android本地app操作相关基础的延伸,然而内容基本没什么联系了(初学者身份瞬间暴露,打一枪换一个地方←_←),就不好意思再添个“续”或者“(2)”了~~
照旧先码字!

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解码一类的耗时操作,最好不要在它们里面进行。


如何解决这个问题

真正的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

这个粉红色其实很难看,单纯当区别用。。。。。。
实战开发如果没有美工,一定要仔细斟酌选取,尽量让自己审美好点!
推荐一个不错的配色方案网站Material Design调色板

<?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>

最终运行效果

截图已经不太能感受到卡了,真机运行更加流畅!

1.gif
上一篇下一篇

猜你喜欢

热点阅读