为了账号安全,请及时绑定邮箱和手机立即绑定

RecyclerView

标签:
Android

一、为什么叫做RecyclerView?   

         1、不关心Item是否显示在正确的位置,如何显示;(LayoutManager)

         2、不关心Item间如何分割;(ItemDecoration)

         3、不关注Item增加与删除的动画效果;(ItemAnimator)

         4、仅仅关注如何回收与复用View。

        (1)通过设置LayoutManager的不同实例来设计RecyclerView的风格;

        (2)通过设置ItemDecoration来设计RecyclerView的分割方式;

        (3)通过设置ItemAnimator来设计RecyclerView的动画效果。


二、与RecyclerView相关的重要类

        1、Adapter

        2、ViewHolder

        3、LayoutManager

        4、ItemDecoration

        5、ItemAnimator


三、RecyclerView能干什么?

        1、ListView(LayoutManager)

        2、GridView(LayoutManager)

        3、横向ListView(LayoutManager)

        4、横向GridView(LayoutManager)

        5、瀑布流(LayoutManager)

        6、定制Item增加与删除动画(ItemAnimator)

        (1)实现ListView

                1>写布局文件

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <RelativeLayout

  3.    xmlns:android="http://schemas.android.com/apk/res/android"

  4.    xmlns:tools="http://schemas.android.com/tools"

  5.    android:layout_width="match_parent"

  6.    android:layout_height="match_parent"

  7.    tools:context="com.qf.day_03.Main3Activity">

  8.    <android.support.v7.widget.RecyclerView

  9.        android:id="@+id/id_recyclerview"

  10.        android:layout_width="match_parent"

  11.        android:layout_height="match_parent">


  12.    </android.support.v7.widget.RecyclerView>


  13. </RelativeLayout>

                2>查找控件

    private void initViews() {        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);    }

                3>获取数据

  1.    private void initDatas() {

  2.        mDatas = new ArrayList<>();

  3.        for (int i = 'A'; i <'z' ; i++) {

  4.            mDatas.add("" + (char) i);


  5.        }

  6.    }

                4>自定义适配器

  1. import android.content.Context;

  2. import android.support.v7.widget.RecyclerView;

  3. import android.view.LayoutInflater;

  4. import android.view.View;

  5. import android.view.ViewGroup;

  6. import android.widget.TextView;


  7. import java.util.List;


  8. /**

  9. * 适配器

  10. */

  11. public class SimpleAdapter extends RecyclerView.Adapter<MyViewHolder> {

  12.    private LayoutInflater mInflater;

  13.    private Context mContext;

  14.    private List<String> mDatas;


  15.    public SimpleAdapter(Context context, List<String> datas) {

  16.        mContext = context;

  17.        mDatas = datas;

  18.        mInflater=LayoutInflater.from(mContext);

  19.    }


  20.    /**

  21.     * 创建ViewHolder

  22.     * @param parent

  23.     * @param viewType

  24.     * @return

  25.     */

  26.    @Override

  27.    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

  28.        View mView = mInflater.inflate(R.layout.item_single, parent, false);

  29.        MyViewHolder mViewHolder = new MyViewHolder(mView);

  30.        return mViewHolder;

  31.    }


  32.    /**

  33.     * 绑定数据

  34.     * @param holder

  35.     * @param position

  36.     */

  37.    @Override

  38.    public void onBindViewHolder(MyViewHolder holder, int position) {

  39.        holder.mTextView.setText(mDatas.get(position));

  40.    }


  41.    /**

  42.     * 返回条目数

  43.     * @return

  44.     */

  45.    @Override

  46.    public int getItemCount() {

  47.        return mDatas.size();

  48.    }

  49. }

  50. class MyViewHolder extends RecyclerView.ViewHolder{

  51.    TextView mTextView;


  52.    public MyViewHolder(View itemView) {

  53.        super(itemView);

  54.        mTextView= (TextView) itemView.findViewById(R.id.id_tv);

  55.    }

  56. }

                5>写Item布局文件

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3.              android:layout_width="match_parent"

  4.             android:background="#4f00"

  5.              android:layout_height="72dp">

  6.    <TextView

  7.        android:id="@+id/id_tv"

  8.        android:gravity="center"

  9.        android:layout_width="match_parent"

  10.        android:layout_height="match_parent"

  11.        />


  12. </FrameLayout>

                6>设置适配器

        mAdapter = new SimpleAdapter(this, mDatas);        mRecyclerView.setAdapter(mAdapter);

                7>为RecyclerView设置布局管理

        //设置RecyclerView的布局管理        mRecyclerView.setLayoutManager(new LinearLayoutManager(Main3Activity.this,LinearLayoutManager.VERTICAL,false));

                8>为RecyclerView的Item设置分割线

        //设置RecyclerView的Item间的分割线        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));

                9>设置RecyclerView的Item间分割线的类

  1. import android.content.Context;

  2. import android.content.res.TypedArray;

  3. import android.graphics.Canvas;

  4. import android.graphics.Rect;

  5. import android.graphics.drawable.Drawable;

  6. import android.support.v7.widget.LinearLayoutManager;

  7. import android.support.v7.widget.RecyclerView;

  8. import android.view.View;


  9. /**

  10. * 设置RecyclerView的Item之间间隔的类

  11. */

  12. public class DividerItemDecoration extends RecyclerView.ItemDecoration {


  13.    private static final int[] ATTRS = new int[]{

  14.            android.R.attr.listDivider

  15.    };


  16.    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;


  17.    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;


  18.    private Drawable mDivider;


  19.    private int mOrientation;


  20.    public DividerItemDecoration(Context context, int orientation) {

  21.        final TypedArray a = context.obtainStyledAttributes(ATTRS);

  22.        mDivider = a.getDrawable(0);

  23.        a.recycle();

  24.        setOrientation(orientation);

  25.    }


  26.    public void setOrientation(int orientation) {

  27.        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {

  28.            throw new IllegalArgumentException("invalid orientation");

  29.        }

  30.        mOrientation = orientation;

  31.    }


  32.    @Override

  33.    public void onDraw(Canvas c, RecyclerView parent) {


  34.        if (mOrientation == VERTICAL_LIST) {

  35.            drawVertical(c, parent);

  36.        } else {

  37.            drawHorizontal(c, parent);

  38.        }


  39.    }



  40.    public void drawVertical(Canvas c, RecyclerView parent) {

  41.        final int left = parent.getPaddingLeft();

  42.        final int right = parent.getWidth() - parent.getPaddingRight();


  43.        final int childCount = parent.getChildCount();

  44.        for (int i = 0; i < childCount; i++) {

  45.            final View child = parent.getChildAt(i);

  46.            android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());

  47.            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child

  48.                    .getLayoutParams();

  49.            final int top = child.getBottom() + params.bottomMargin;

  50.            final int bottom = top + mDivider.getIntrinsicHeight();

  51.            mDivider.setBounds(left, top, right, bottom);

  52.            mDivider.draw(c);

  53.        }

  54.    }


  55.    public void drawHorizontal(Canvas c, RecyclerView parent) {

  56.        final int top = parent.getPaddingTop();

  57.        final int bottom = parent.getHeight() - parent.getPaddingBottom();


  58.        final int childCount = parent.getChildCount();

  59.        for (int i = 0; i < childCount; i++) {

  60.            final View child = parent.getChildAt(i);

  61.            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child

  62.                    .getLayoutParams();

  63.            final int left = child.getRight() + params.rightMargin;

  64.            final int right = left + mDivider.getIntrinsicHeight();

  65.            mDivider.setBounds(left, top, right, bottom);

  66.            mDivider.draw(c);

  67.        }

  68.    }


  69.    @Override

  70.    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {

  71.        if (mOrientation == VERTICAL_LIST) {

  72.            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());

  73.        } else {

  74.            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);

  75.        }

  76.    }

  77. }

                10>秒变GridView

  1. mRecyclerView.setLayoutManager(new GridLayoutManager(Main3Activity.this,3));

  2. //mRecyclerView.setLayoutManager(new GridLayoutManager(this,3,GridLayoutManager.HORIZONTAL,false));

        (2)实现瀑布流布局

                                1>写布局文件

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <RelativeLayout

  3.    xmlns:android="http://schemas.android.com/apk/res/android"

  4.    xmlns:tools="http://schemas.android.com/tools"

  5.    android:layout_width="match_parent"

  6.    android:layout_height="match_parent"

  7.    tools:context="com.qf.day_03.Main3Activity">

  8.    <android.support.v7.widget.RecyclerView

  9.        android:id="@+id/id_recyclerview"

  10.        android:layout_width="match_parent"

  11.        android:layout_height="match_parent">


  12.    </android.support.v7.widget.RecyclerView>


  13. </RelativeLayout>

                2>查找控件

    private void initViews() {        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);    }

                3>获取数据

  1.    private void initDatas() {

  2.        mDatas = new ArrayList<>();

  3.        for (int i = 'A'; i <'z' ; i++) {

  4.            mDatas.add("" + (char) i);


  5.        }

  6.    }

                4>自定义适配器

  1. import android.content.Context;

  2. import android.support.v7.widget.RecyclerView;

  3. import android.view.LayoutInflater;

  4. import android.view.View;

  5. import android.view.ViewGroup;

  6. import android.widget.TextView;


  7. import java.util.ArrayList;

  8. import java.util.List;


  9. /**

  10. * 瀑布流适配器

  11. */

  12. public class StaggeredAdapter extends RecyclerView.Adapter<StaggeredAdapter.MyViewHolder>{

  13.    private LayoutInflater mInflater;

  14.    private Context mContext;

  15.    private List<String> mDatas;

  16.    private List<Integer> mHeights;


  17.    public StaggeredAdapter(Context context, List<String> datas) {

  18.        mContext = context;

  19.        mDatas = datas;

  20.        mInflater=LayoutInflater.from(mContext);

  21.        mHeights = new ArrayList<>();

  22.        for (int i = 0; i < mDatas.size(); i++) {

  23.            mHeights.add((int) (100 + Math.random() * 300));

  24.        }


  25.    }


  26.    /**

  27.     * 创建ViewHolder

  28.     * @param parent

  29.     * @param viewType

  30.     * @return

  31.     */

  32.    @Override

  33.    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

  34.        View mView = mInflater.inflate(R.layout.item_single, parent, false);

  35.        MyViewHolder mViewHolder = new MyViewHolder(mView);

  36.        return mViewHolder;

  37.    }


  38.    /**

  39.     * 绑定数据

  40.     * @param holder

  41.     * @param position

  42.     */

  43.    @Override

  44.    public void onBindViewHolder(MyViewHolder holder, int position) {

  45.        ViewGroup.LayoutParams mParams = holder.itemView.getLayoutParams();

  46.        mParams.height = mHeights.get(position);

  47.        holder.itemView.setLayoutParams(mParams);

  48.        holder.mTextView.setText(mDatas.get(position));

  49.    }


  50.    /**

  51.     * 返回条目数

  52.     * @return

  53.     */

  54.    @Override

  55.    public int getItemCount() {

  56.        return mDatas.size();

  57.    }

  58.    class MyViewHolder extends RecyclerView.ViewHolder{

  59.        TextView mTextView;


  60.        public MyViewHolder(View itemView) {

  61.            super(itemView);

  62.            mTextView= (TextView) itemView.findViewById(R.id.id_tv);

  63.        }

  64. }


  65. }

                 5>写Item布局文件

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3.              android:layout_width="match_parent"

  4.             android:background="#4f00"

  5.              android:layout_height="72dp">

  6.    <TextView

  7.        android:id="@+id/id_tv"

  8.        android:gravity="center"

  9.        android:layout_width="match_parent"

  10.        android:layout_height="match_parent"

  11.        />


  12. </FrameLayout>

                6>设置适配器

 mAdapter = new StaggeredAdapter(this, mDatas); mRecyclerView.setAdapter(mAdapter);

                7>为RecyclerView设置布局管理

mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));

        (3)增加和删除Item的动画

mRecyclerView.setItemAnimator(new DefaultItemAnimator());

        (4)设置Item监听事件

                4.1>在适配器中定义点击事件的接口

  1. /**

  2.     * 设置点击事件的接口

  3.     */

  4.    public interface OnItemClickListener{

  5.        void onItemClick(View view, int position);

  6.        void onItemLongClick(View view,int position);

  7.    }


  8.    private OnItemClickListener mOnItemClickListener;


  9.    public void setOnItemClickListener(OnItemClickListener listener) {

  10.        this.mOnItemClickListener = listener;

  11.    }

                4.2>在适配器的onBindViewHolder方法中设置Item的点击事件

  1. if (mOnItemClickListener != null) {

  2.        holder.itemView.setOnClickListener(new View.OnClickListener() {

  3.            @Override

  4.            public void onClick(View v) {

  5. //获取布局上的位置

                        int mPosition = holder.getLayoutPosition();

  6.                    mOnItemClickListener.onItemClick(holder.itemView,mPosition);


  7.            }

  8.        });


  9.            //longclick

  10.            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {

  11.                @Override

  12.                public boolean onLongClick(View v) {

  13. //获取布局上的位置(在有Item增加和减少的时候有用)

                        int mPosition = holder.getLayoutPosition();

  14.                    mOnItemClickListener.onItemLongClick(holder.itemView,mPosition);

  15.                    return false;

  16.                }

  17.            });

  18.        }

                4.3>在Activity中为适配器设置点击事件

  1. mAdapter.setOnItemClickListener(new SimpleAdapter.OnItemClickListener() {

  2.            @Override

  3.            public void onItemClick(View view, int position) {

  4.                Toast.makeText(Main3Activity.this, "click:"+position, Toast.LENGTH_SHORT).show();

  5.            }


  6.            @Override

  7.            public void onItemLongClick(View view, int position) {

  8.                Toast.makeText(Main3Activity.this, "longclick:"+position, Toast.LENGTH_SHORT).show();

  9.            }

  10.        });

四、注意事项

        1、ItemAnimator在使用的时候,不要使用notifyItemChanged(),而是要使用notifyItemInserted();和notifyItemMoved();。

        2、RecyclerView没有提供Item的Click事件,所以需要手动在Adapter中提供ItemClick/longClick的回调。

        3、RecyclerView可以实现在ListView、GridView、横向ListView、横向 GridView、瀑布流之间的灵活切换。

原文链接:http://www.apkbus.com/blog-815579-62010.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消