• RecyclerView 初体验


    目录:

    1.基本使用

    2.ItemDecoration   Item分割线

    3.LayoutManager  

    4.ItemAnimator   Item动画

    5.Click and LongClick  Item点击事件

    --------------------

    1.基本使用

    RecyclerView的使用中最重要的是Adapter,Adapter中最重要的是ViewHolder。先看最简单的RecyclerView的Adapter实现:

    class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>
        {
    
            @Override
            public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
            {
                MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
                        HomeActivity.this).inflate(R.layout.item_home, parent,
                        false));
                return holder;
            }
    
            @Override
            public void onBindViewHolder(MyViewHolder holder, int position)
            {
                holder.tv.setText(mDatas.get(position));
            }
    
            @Override
            public int getItemCount()
            {
                return mDatas.size();
            }
    
            class MyViewHolder extends ViewHolder
            {
    
                TextView tv;
    
                public MyViewHolder(View view)
                {
                    super(view);
                    tv = (TextView) view.findViewById(R.id.id_num);
                }
            }
        }
    

    RecyclerView的基本使用 代码:

    mRecyclerView = findView(R.id.id_recyclerview);
    //设置布局管理器
    mRecyclerView.setLayoutManager(layout);
    //设置adapter
    mRecyclerView.setAdapter(adapter)
    //设置Item增加、移除动画
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    //添加分割线
    mRecyclerView.addItemDecoration(new DividerItemDecoration(
                    getActivity(), DividerItemDecoration.HORIZONTAL_LIST));

    主要通过上面代码,即可实现和ListView类似的效果

    2.ItemDecoration   Item分割线

    我们可以通过该方法添加分割线: 

    mRecyclerView.addItemDecoration() 

      2.1 ListView型分割线 实现类

      

    package com.devilwwj.myapplication_recyclerview;
    
    /*
     * Copyright (C) 2014 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * limitations under the License.
     */
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.RecyclerView.State;
    import android.util.Log;
    import android.view.View;
    
    
    /**
     * 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);
            }
        }
    }

      2.2 GridView型分割线 实现类

      

    package com.devilwwj.myapplication_recyclerview;
    
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.RecyclerView.LayoutManager;
    import android.support.v7.widget.RecyclerView.State;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    import android.view.View;
    
    public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
    
        private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
        private Drawable mDivider;
        private Paint mPaint;
        private int mDividerHeight = 1;
    
        public DividerGridItemDecoration(Context context) {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            mDivider = a.getDrawable(0);
            a.recycle();
        }
    
        /**
         * 自定义分割线
         *
         * @param context
         * @param drawableId 分割线图片
         */
        public DividerGridItemDecoration(Context context, int drawableId) {
            mDivider = ContextCompat.getDrawable(context, drawableId);
            mDividerHeight = mDivider.getIntrinsicHeight();
        }
    
        /**
         * 自定义分割线
         *
         * @param context
         * @param dividerHeight 分割线高度
         * @param dividerColor  分割线颜色
         */
        public DividerGridItemDecoration(Context context, int dividerHeight, int dividerColor) {
            mDividerHeight = dividerHeight;
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(dividerColor);
            mPaint.setStyle(Paint.Style.FILL);
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, State state) {
            drawHorizontal(c, parent);
            drawVertical(c, parent);
        }
    
        private int getSpanCount(RecyclerView parent) {
            // 列数
            int spanCount = -1;
            LayoutManager layoutManager = parent.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager) {
                spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
            }
            return spanCount;
        }
    
        // 绘制水平线
        public void drawHorizontal(Canvas c, RecyclerView parent) {
            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.getLeft() - params.leftMargin;
                final int right = child.getRight() + params.rightMargin + mDividerHeight;
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDividerHeight;
                if (mDivider != null) {
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(c);
                }
                if (mPaint != null) {
                    c.drawRect(left, top, right, bottom, mPaint);
                }
            }
        }
    
        // 绘制垂直线
        public void drawVertical(Canvas c, RecyclerView parent) {
            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 top = child.getTop() - params.topMargin;
                final int bottom = child.getBottom() + params.bottomMargin;
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDividerHeight;
                if (mDivider != null) {
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(c);
                }
                if (mPaint != null) {
                    c.drawRect(left, top, right, bottom, mPaint);
                }
            }
        }
    
        // 判断是否是最后一列
        private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {
            LayoutManager layoutManager = parent.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager) {
                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
                {
                    return true;
                }
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
                if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                    if ((pos + 1) % spanCount == 0) {
                        // 如果是最后一列,则不需要绘制右边
                        return true;
                    }
                } else {
                    childCount = childCount - childCount % spanCount;
                    if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
                        return true;
                }
            }
            return false;
        }
    
        // 判断是否是最后一行
        private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
            LayoutManager layoutManager = parent.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager) {
                childCount = childCount - childCount % spanCount;
                if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
                    return true;
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
                // StaggeredGridLayoutManager 且纵向滚动
                if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                    childCount = childCount - childCount % spanCount;
                    // 如果是最后一行,则不需要绘制底部
                    if (pos >= childCount)
                        return true;
                } else
                // StaggeredGridLayoutManager 且横向滚动
                {
                    // 如果是最后一行,则不需要绘制底部
                    if ((pos + 1) % spanCount == 0) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        @Override
        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
            int spanCount = getSpanCount(parent);
            int childCount = parent.getAdapter().getItemCount();
            if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
            {
                outRect.set(0, 0, mDividerHeight, 0);
            } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
            {
                outRect.set(0, 0, 0, mDividerHeight);
            } else {
                outRect.set(0, 0, mDividerHeight, mDividerHeight);
            }
        }
    }

    3.LayoutManager

      3.1 LinearLayoutManager 线性布局管理器

      3.2 GridLayoutManager 网格布局管理器

      3.3 StaggeredGridLayoutManager 网格布局管理器

    4.ItemAnimator   Item动画

    // 设置item动画
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    注意,这里更新数据集不是用adapter.notifyDataSetChanged()而是 
    notifyItemInserted(position)notifyItemRemoved(position) 
    否则没有动画效果。 
    为上述adapter中添加了两个方法:

    public void addData(int position) {
            mDatas.add(position, "Insert One");
            notifyItemInserted(position);
    }
    
    public void removeData(int position) {
            mDatas.remove(position);
            notifyItemRemoved(position);
    }

    5.Click and LongClick  Item点击事件

    adapter中自己去提供回调

    class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>
    {
    
    //...
        public interface OnItemClickLitener
        {
            void onItemClick(View view, int position);
            void onItemLongClick(View view , int position);
        }
    
        private OnItemClickLitener mOnItemClickLitener;
    
        public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
        {
            this.mOnItemClickLitener = mOnItemClickLitener;
        }
    
        @Override
        public void onBindViewHolder(final MyViewHolder holder, final int position)
        {
            holder.tv.setText(mDatas.get(position));
    
            // 如果设置了回调,则设置点击事件
            if (mOnItemClickLitener != null)
            {
                holder.itemView.setOnClickListener(new OnClickListener()
                {
                    @Override
                    public void onClick(View v)
                    {
                        int pos = holder.getLayoutPosition();
                        mOnItemClickLitener.onItemClick(holder.itemView, pos);
                    }
                });
    
                holder.itemView.setOnLongClickListener(new OnLongClickListener()
                {
                    @Override
                    public boolean onLongClick(View v)
                    {
                        int pos = holder.getLayoutPosition();
                        mOnItemClickLitener.onItemLongClick(holder.itemView, pos);
                        return false;
                    }
                });
            }
        }
    //...
    }

    Activity中去设置监听:

    mAdapter.setOnItemClickLitener(new OnItemClickLitener()
            {
    
                @Override
                public void onItemClick(View view, int position)
                {
                    Toast.makeText(HomeActivity.this, position + " click",
                            Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void onItemLongClick(View view, int position)
                {
                    Toast.makeText(HomeActivity.this, position + " long click",
                            Toast.LENGTH_SHORT).show();
                            mAdapter.removeData(position);
                }
            });

    源码:http://pan.baidu.com/s/1slRiugX  (提取码:yrfu)

    参考:http://blog.csdn.net/lmj623565791/article/details/45059587

  • 相关阅读:
    C++11特性
    DBC文件小结
    关于宏定义
    CentOS 6.5下Zabbix的安装配置
    CentOS下搭建LAMP环境详解
    VS2010中汉字拷贝到Word出现乱码问题解决
    DLL注入
    数组赋值
    CDC的StretchBlt函数载入位图时图片失真问题
    2019年下半年Web前端开发初级理论考试
  • 原文地址:https://www.cnblogs.com/blackmonkey/p/6582993.html
Copyright © 2020-2023  润新知