zoukankan      html  css  js  c++  java
  • 还在用ListView?

    还在用Lisview?RecyclerView都已经出来一年多了!

    想必大家多或多或少的接触过或者了解过RecyclerView,为什么没实用起来,原因大概例如以下?

    • ListView我用的挺好的,为什么要换RecyclerView?
    • ListView稳定。熟悉。还知道非常多开源库。特别的好用!
    • RecyclerView不能加入头部,ListView能!


    RecyclerView

    RecyclerView最大的优势就是灵活,RecyclerView仅仅需改变一行代码就能够变化多种不同的布局显示排版。这一点对于开发人员是非常方便的!

    还有RecyclerView.Adapter。比BaseAdapter做了更好的封装,把BaseAdapter的getView方法拆分成onCreateViewHolder方法和onBindViewHolder方法,强制须要创建ViewHolder,这样的优点就是避免了刚開始学习的人写性能不佳的代码

    在Andorid 5.0出来不久,我就已经写过RecyclerView的简介以及基本使用,不了解的能够看看ListView升级版RecyclerView,了解过的同学能够忽略,并往下看。

    在实战中我们会遇到什么问题?

    get到以下的技能就能够在使用RcyclerView的大路上畅通无阻了!

    • 加入切割线
    • 加入点按效果
    • 列表动画
    • 改变某个数据保持当前位置
    • 加入头部尾部
    • 列表分组
    • 各种效果集成Demo
    • 更灵活的RecyclerView

    加入切割线

    //通过以下方法加入切割线
    mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
    DividerItemDecoration.VERTICAL_LIST));

    须要RecyclerView.ItemDecoration这个抽象类实现一些方法
    (兴许有更偷懒的方法)

    /**
     * This class is from the v7 samples of the Android SDK. It's not by me!
     * <p/>
     * See the license above for details.
     */
    public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    
        private static final int[] ATTRS = new int[]{
                android.R.attr.listDivider
        };
    
        public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    
        public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
    
        private Drawable mDivider;
    
        private int mOrientation;
    
        public DividerItemDecoration(Context context, int orientation) {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            mDivider = a.getDrawable(0);
            a.recycle();
            setOrientation(orientation);
        }
    
        public void setOrientation(int orientation) {
            if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
                throw new IllegalArgumentException("invalid orientation");
            }
            mOrientation = orientation;
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent) {
            Log.v("recyclerview - itemdecoration", "onDraw()");
    
            if (mOrientation == VERTICAL_LIST) {
                drawVertical(c, parent);
            } else {
                drawHorizontal(c, parent);
            }
    
        }
    
    
        public void drawVertical(Canvas c, RecyclerView parent) {
            final int left = parent.getPaddingLeft();
            final int right = parent.getWidth() - parent.getPaddingRight();
    
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    
        public void drawHorizontal(Canvas c, RecyclerView parent) {
            final int top = parent.getPaddingTop();
            final int bottom = parent.getHeight() - parent.getPaddingBottom();
    
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    
        @Override
        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
            if (mOrientation == VERTICAL_LIST) {
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            } else {
                outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
            }
        }
    }

    看到这里应该有同学吐槽了,就加入一根线至于吗?还须要重写方法,ListView可是仅仅须要简单配置一下就好了。

       android:divider="@color/grey"
       android:dividerHeight="5dp"

    为此我也感觉太麻烦,于是我想了一个办法:
    直接在item_view里面底部自己加入一根线布局,这样就无需重写了,而且这样还有个优点就是。假设细心的同学会发现。加入切割线。最后一个item以下不会有切割线。显然当数据量不足一个屏幕的时候显得非常突兀,可是在item_view以下加入一个线的布局则不会出现这样的情况

    加入点按效果

    RecyclerView直接在item_view里面配置就可以

    动画

    一个好的用户体验就是要有操作动画的过渡。而不是生硬的刷新列表。

    推荐一个RecyclerView的动画库(recyclerview-animators
    这里写图片描写叙述

    RecyclerView自带加入、删除动画。而ListView则需加入额外的代码才干实现。

    • 删除调用RecyclerView的adapter的notifyItemRemoved
    • 加入调用RecyclerView的adapter的notifyItemInserted

    说到adapter我们就来说说RecyclerView.Adapter和BaseAdapter相比,额外提供了一下这些方法:

    // 数据发生了改变。那调用这种方法,传入改变对象的位置。
    public final void notifyItemChanged(int position);
    
    // 能够刷新从positionStart開始itemCount数量的item了
    public final void notifyItemRangeChanged(int positionStart, int itemCount);
    
    // 加入,传入对象的位置。
    public final void notifyItemInserted(int position);
    
    // 删除。传入对象的位置。

    public final void notifyItemRemoved(int position); // 对象从fromPosition移动到toPosition public final void notifyItemMoved(int fromPosition, int toPosition); //批量加入 public final void notifyItemRangeInserted(int positionStart, int itemCount); //批量删除 public final void notifyItemRangeRemoved(int positionStart, int itemCount);

    改变列表某个布局状态且保持当前位置

    这样的需求是普遍存在的,就是改变列表某一个item数据,然后刷新列表。假设是ListView刷新后则会回到最顶部。而RecyclerView相同的操作可是原来滑动的位置不变。

    各种解决方式的RecyclerView的Adapter

    BaseRecyclerViewAdapterHelper

    效果展示

    更灵活的RecyclerView

    twoway-view
    封装了RecyclerView经常用法。如click等等,以及支持了很多其它不同的布局。使得RecyclerView使用起来更简单!


    这里写图片描写叙述

    造起来!小伙伴们!

  • 相关阅读:
    695. 岛屿的最大面积(深搜)
    147. 对链表进行插入排序(排序)
    566. 重塑矩阵(模拟)
    238. 除自身以外数组的乘积(前后缀积)
    29.Java基础_接口
    C++ STL queue
    C++ STL stack
    C++ STL string
    C面向接口编程和C++多态案例
    单例模式入门
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7253482.html
Copyright © 2011-2022 走看看