您的位置:

提高Android RecyclerView性能的技巧

一、使用ViewHolder提升性能

在Android 5.0以前,RecyclerView使用ViewHolder来重用布局并减少内存消耗。ViewHolder是一个包含视图组件的容器,可以提高视图重用的效率。我们可以通过继承RecyclerView.ViewHolder来创建ViewHolder。

class MyViewHolder extends RecyclerView.ViewHolder {
    TextView name;
    TextView age;
    public MyViewHolder(View view) {
        super(view);
        name = (TextView) view.findViewById(R.id.name);
        age = (TextView) view.findViewById(R.id.age);
    }
}

ViewHolder的使用可以减少inflate布局的次数,从而提高RecyclerView的性能。在onBindViewHolder()方法中,我们可以将数据绑定到ViewHolder中的视图组件上。

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.name.setText(mData.get(position).getName());
    holder.age.setText(mData.get(position).getAge());
}

二、使用DiffUtil优化数据更新

RecyclerView经常需要更新数据,而DiffUtil可以提高数据更新的效率。DiffUtil是一个工具类,用于计算两个数据集之间的差异。在数据更新时,我们可以使用DiffUtil来计算数据集差异,从而只更新变化的部分,减少不必要的重绘和动画效果。

class MyDiffCallback extends DiffUtil.Callback {
    private List oldList;
    private List
    newList;
    public MyDiffCallback(List
     oldList, List
      newList) {
        this.oldList = oldList;
        this.newList = newList;
    }
    @Override
    public int getOldListSize() {
        return oldList.size();
    }
    @Override
    public int getNewListSize() {
        return newList.size();
    }
    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldList.get(oldItemPosition).getId() == newList.get(newItemPosition).getId();
    }
    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        MyData oldData = oldList.get(oldItemPosition);
        MyData newData = newList.get(newItemPosition);
        return oldData.getName().equals(newData.getName()) && oldData.getAge() == newData.getAge();
    }
}

     
    
   
  

DiffUtil需要实现四个回调方法,getOldListSize()和getNewListSize()返回旧数据集和新数据集的大小,areItemsTheSame()判断两个数据是否为同一个item,areContentsTheSame()判断同一位置的两条数据是否内容相同。

在数据更新时,我们需要在新数据集合成前使用DiffUtil计算差异,将差异应用到适配器中并更新RecyclerView。

MyDiffCallback diffCallback = new MyDiffCallback(mData, newData);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
mData = newData;
diffResult.dispatchUpdatesTo(this);

三、使用ItemDecoration美化界面和提升性能

ItemDecoration可以为RecyclerView添加自定义的分割线、颜色、边距等,使界面更加美观,同时也可以提高RecyclerView的性能。我们通常使用RecyclerView.ItemDecoration来创建ItemDecoration。

public class MyItemDecoration extends RecyclerView.ItemDecoration {
    private int mDividerHeight;
    private Paint mPaint;
    public MyItemDecoration(int dividerHeight, int dividerColor) {
        mDividerHeight = dividerHeight;
        mPaint = new Paint();
        mPaint.setColor(dividerColor);
        mPaint.setStyle(Paint.Style.FILL);
    }
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.bottom = mDividerHeight;
    }
    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        for (int i = 0; i < parent.getChildCount() - 1; i++) {
            View child = parent.getChildAt(i);
            float top = child.getBottom();
            canvas.drawRect(left, top, right, top + mDividerHeight, mPaint);
        }
    }
}

在RecyclerView中添加ItemDecoration。

MyItemDecoration itemDecoration = new MyItemDecoration(dp2px(1), Color.GRAY);
recyclerView.addItemDecoration(itemDecoration);

四、使用RecyclerView滑动监听减少内存消耗

RecyclerView在滑动时,会大量的创建和销毁视图,如果在滑动过程中同时处理复杂的数据操作,会导致卡顿或者OOM。因此,我们可以在RecyclerView滑动时停止加载图片或者其他占用内存的操作,从而减少内存消耗,提高滑动性能。我们可以通过RecyclerView的addOnScrollListener()监听RecyclerView的滑动状态。

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        switch (newState) {
            case RecyclerView.SCROLL_STATE_IDLE:
                //滑动停止,可以执行数据加载等其他操作
                break;
            case RecyclerView.SCROLL_STATE_DRAGGING:
                //手指触摸滑动中,应停止数据加载等流操作
                break;
            case RecyclerView.SCROLL_STATE_SETTLING:
                //惯性滑动中,应停止数据加载等流操作
                break;
        }
    }
});

五、使用LayoutManager优化布局

LayoutManager是RecyclerView中布局管理器的基类,可以用于控制RecyclerView中子View的布局方式。使用LayoutManager可以实现多种复杂的布局,并且可以优化RecyclerView的性能。下面介绍几种常见的LayoutManager。

1. LinearLayoutManager

LinearLayoutManager是RecyclerView默认的布局管理器,控制子View的排列方向,有三种排列方式:VERTICAL、HORIZONTAL、Horizontal.VERTICAL。

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);

2. GridLayoutManager

GridLayoutManager可以将子View排列成网格形式。可以通过GridLayoutManager的构造函数来控制列数。

GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);

3. StaggeredGridLayoutManager

StaggeredGridLayoutManager可以将子View排列成不规则的网格形式。可以通过StaggeredGridLayoutManager的构造函数来控制列数和方向。

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);

完整代码示例

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private List mData;
    private MyAdapter mAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recyclerView);
        initData();
        mAdapter = new MyAdapter(mData);
        recyclerView.setAdapter(mAdapter);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        MyItemDecoration itemDecoration = new MyItemDecoration(dp2px(1), Color.GRAY);
        recyclerView.addItemDecoration(itemDecoration);
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE:
                        //滑动停止,可以执行数据加载等其他操作
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING:
                        //手指触摸滑动中,应停止数据加载等流操作
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING:
                        //惯性滑动中,应停止数据加载等流操作
                        break;
                }
            }
        });
    }
    private void initData() {
        mData = new ArrayList<>();
        mData.add(new MyData(1, "张三", 18));
        mData.add(new MyData(2, "李四", 20));
        mData.add(new MyData(3, "王五", 22));
        mData.add(new MyData(4, "赵六", 21));
    }
    public int dp2px(float dpValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
    class MyAdapter extends RecyclerView.Adapter
    {
        private List
     mData;
        public MyAdapter(List
      data) {
            mData = data;
        }
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
            MyViewHolder viewHolder = new MyViewHolder(view);
            return viewHolder;
        }
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.name.setText(mData.get(position).getName());
            holder.age.setText(mData.get(position).getAge());
        }
        @Override
        public int getItemCount() {
            return mData.size();
        }
    }
    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name;
        TextView age;
        public MyViewHolder(View view) {
            super(view);
            name = (TextView) view.findViewById(R.id.name);
            age = (TextView) view.findViewById(R.id.age);
        }
    }
    class MyData {
        private int id;
        private String name;
        private int age;
        public MyData(int id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
        public int getId() {
            return id;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
    }
    class MyItemDecoration extends RecyclerView.ItemDecoration {
        private int mDividerHeight;
        private Paint mPaint;
        public MyItemDecoration(int dividerHeight, int dividerColor) {
            mDividerHeight = dividerHeight;
            mPaint = new Paint();
            mPaint.setColor(dividerColor);
            mPaint.setStyle(Paint.Style.FILL);
        }
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            outRect.bottom = mDividerHeight;
        }
        @Override
        public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
            for (int i = 0; i < parent.getChildCount() - 1; i++) {
                View child = parent.getChildAt(i);
                float top = child.getBottom();
                canvas.drawRect(left, top, right, top + mDividerHeight, mPaint);
            }
        }
    }
    class MyDiffCallback extends DiffUtil.Callback {
        private List
       oldList;
        private List
       
        newList; public MyDiffCallback(List
        
         oldList, List
         
          newList) { this.oldList = oldList; this.newList = newList; } @Override public int getOldListSize() { return oldList.size(); } @Override public int getNewListSize() { return newList.size(); } @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { return oldList.get(oldItemPosition).getId() == newList.get(newItemPosition).getId(); } @Override public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { MyData oldData = oldList.get(oldItemPosition); MyData newData = newList.get(newItemPosition); return oldData.getName().equals(newData.getName()) && oldData.getAge() == newData.getAge(); } } }
         
        
       
      
     
    
   
  
提高Android应用程序性能的技巧

随着Android设备的普及和市场的竞争,Android应用程序的性能表现越来越重要。在这篇文章中,我们将探讨如何通过一些技巧来提高Android应用程序的性能。 一、延迟加载 延迟加载是一种常用的技

2023-12-08
提高Android系统性能的技巧

2023-05-14
提高android应用性能的几种技巧

2023-05-14
提高Android RecyclerView性能的技巧

2023-05-14
提高Android应用程序性能的技巧

2023-05-14
提高用户体验的Android enabled技巧

2023-05-14
Android Open Source Project:提高

2023-05-14
提高Android用户体验的几个实用技巧

一、使用RecyclerView进行列表展示 在Android应用中,列表的展示是非常常见的功能,如展示新闻列表、商品列表、聊天记录、好友列表等。传统的方式是使用ListView组件进行展示,但是Li

2023-12-08
提高Android应用性能的关键布局优化技巧

2023-05-14
提高Android应用性能的关键技巧

2023-05-14
提高Android Studio使用效率的10个技巧

Android Studio作为Android开发的主流开发工具,在日常的开发中会频繁使用。如何提高Android Studio的使用效率,可以让我们更快更高效地完成开发任务。本文将介绍10个技巧,旨

2023-12-08
提高Android Studio使用效率的10个技巧

Android Studio作为Android开发的主流开发工具,在日常的开发中会频繁使用。如何提高Android Studio的使用效率,可以让我们更快更高效地完成开发任务。本文将介绍10个技巧,旨

2023-12-08
提高Android应用性能的小技巧

2023-05-14
提高Android应用性能的关键技术

2023-05-14
Android应用开发的必备技能——学会使用Recycler

2023-05-14
Android开发技巧:提高应用用户体验的方法

2023-05-14
提高Android应用页面性能的方法

2023-05-14
让你的Android列表内容更新更流畅的技巧

2023-05-14
Android Recyclerview:高效展示列表数据

2023-05-14
提高应用程序性能的Android优化建议

Android市场上有着数以万计的应用程序,而用户对于应用程序的要求也越来越高,特别是关于性能的表现。本文将从以下几个方面介绍Android优化建议,以提高应用程序的性能:一、减少内存开销在Andro

2023-12-08