欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RecyclerView的简单使用

程序员文章站 2022-06-05 12:44:28
...

前言

RecyclerView不仅可以完全取缔ListView和GridView,还可以有很多其他的效果,可以非常炫酷,今天先来记录下最简单的使用.

RecyclerView是自Android 5.0之后才发布的,要使用它要先根据自己sdk的版本进行导包:

compile 'com.android.support:recyclerview-v7:25.3.1'

导包完成后就可以开始使用了.

1.控件使用

RecyclerView是一个控件,它的使用方法跟ListView的用法差不多,直接在布局中使用.

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#5555"
    tools:context="com.simon.demo.my.Main2Activity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/add_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="添加item"/>

        <Button
            android:id="@+id/delete_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="删除item"/>
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:paddingLeft="3dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

2.Adapter和LayoutManager

在使用RecyclerView时候,必须指定一个适配器Adapter和一个布局管理器LayoutManager。适配器继承RecyclerView.Adapter类,具体实现类似ListView的适配器,取决于数据信息以及展示的UI。布局管理器用于确定RecyclerView中Item的展示方式以及决定何时复用已经不可见的Item,避免重复创建以及执行高成本的findViewById()方法。

①LayoutManager布局管理器

RecyclerView提供了三种布局管理器:

  • LinerLayoutManager 以垂直或者水平列表方式展示Item
  • GridLayoutManager 以网格方式展示Item
  • StaggeredGridLayoutManager 以瀑布流方式展示Item
//这里使用了线性垂直列表
mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLinearLayoutManager);

②Adapter适配器

创建一个类继承RecyclerView.Adapter

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder>{

    private final Context context;
    private final ArrayList<String> mData;

    public RecycleAdapter(Context c, ArrayList<String> data){
        this.context = c;
        this.mData = data;
    }

    //获取item布局,并创建ViewHolder与之绑定
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //这里填充的布局root写parent的话,会只显示一个item,改为null后才正常显示
        //解决http://blog.csdn.net/fantasiasango/article/details/52188064
        //如果用View.inflate填充的布局没有调用到设置的属性
//        View view = View.inflate(parent.getContext(), R.layout.view_rv_item, null);
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_rv_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    //
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTx.setText(mData.get(position));
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
 //有写情况下需要手动设置属性,不然布局会显示不正常
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        itemView.setLayoutParams(layoutParams);
        private final TextView mTx;

        public ViewHolder(View itemView) {
            super(itemView);
            mTx = (TextView) itemView.findViewById(R.id.item_tv);
        }
    }
}

Activity中使用代码

 mRecycleAdapter = new RecycleAdapter(this,getData());
 mRecyclerView.setAdapter(mRecycleAdapter);

 //模拟数据
    private ArrayList<String> getData() {
        ArrayList<String> strings = new ArrayList<>();
        for(int i = 0; i < 50; i++) {
            strings.add("我是超人"+i);
        }
        return strings;
    }

③Decoration修饰器

这是用来自定义RecycleView的样式,decoration的样式可以同时使用多个,不同的decoration效果会重叠起来,从而达到不同的效果.

主要使用的三个方法:

public void onDraw(Canvas c, RecyclerView parent, State state)
public void onDrawOver(Canvas c, RecyclerView parent, State state)
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)

举例使用:

public class MyItemDecoration extends RecyclerView.ItemDecoration {

    private final Paint mPaint;
    private final int mDividerHeight;

    public MyItemDecoration(Context context) {
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mDividerHeight = 10;
    }

    //    这两个方法都是用于绘制间隔样式
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
        int childCount = parent.getChildCount();
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();

        for (int i = 0; i < childCount - 1; i++) {
            View view = parent.getChildAt(i);
            int top = view.getBottom();
            int bottom = view.getBottom() + 5;
            Log.v("cherish233", "left:" + left + "---" + "top:" + top + "---" + "right:" + right + "---" + "bottom:" + bottom + "---");
            c.drawRect(left, top, right, bottom, mPaint);
        }
        //        View view = parent.getChildAt(0);
        //        int top = view.getBottom();
        //        int bottom = view.getBottom() + mDividerHeight;
        //        Log.v("cherish233", "left:" + left + "---" + "top:" + top + "---" + "right:" + right + "---" + "bottom:" + bottom + "---");
        //        c.drawRect(left, top, right, bottom, mPaint);


    }

    //设置item的偏移量,偏移的部分用于填充间隔样式
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.bottom = mDividerHeight;

    }

}

在Activity中的使用代码

mMyItemDecoration = new MyItemDecoration(this);
mRecyclerView.addItemDecoration(mMyItemDecoration);

完整的Activity代码:

public class Main2Activity extends AppCompatActivity implements View.OnClickListener {

    private Button mAddBtn;
    private Button mDeleteBtn;
    private RecyclerView mRecyclerView;
    private LinearLayout mActivityMain2;
    private LinearLayoutManager mLinearLayoutManager;
    private RecycleAdapter mRecycleAdapter;
    private MyItemDecoration mMyItemDecoration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
        initData();
    }

    private void initData() {
        mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mRecycleAdapter = new RecycleAdapter(this,getData());
        mMyItemDecoration = new MyItemDecoration(this);

        mRecyclerView.setLayoutManager(mLinearLayoutManager);
        mRecyclerView.setAdapter(mRecycleAdapter);
        mRecyclerView.addItemDecoration(mMyItemDecoration);
    }

    //模拟数据
    private ArrayList<String> getData() {
        ArrayList<String> strings = new ArrayList<>();
        for(int i = 0; i < 50; i++) {
            strings.add("我是超人"+i);
        }
        return strings;
    }

    private void initView() {

        mAddBtn = (Button) findViewById(R.id.add_btn);
        mAddBtn.setOnClickListener(this);
        mDeleteBtn = (Button) findViewById(R.id.delete_btn);
        mDeleteBtn.setOnClickListener(this);
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.add_btn:

                break;
            case R.id.delete_btn:

                break;
        }
    }
}

最终效果:
RecyclerView的简单使用

3.添加和删除

要想添加和删除数据,只需要在Adapter中添加两个方法

//添加数据
    public void addNewItem(){
        if(mData == null) {
            mData = new ArrayList<>();
        }
        mData.add(0, "new Item");
        //用notifyItemInserted(0)来刷新需要更新的Item,如果用notifyDataSetChanged()没有动画效果
        notifyItemInserted(0);
    }

    //删除数据
    public void deleteItem(int position) {
        if (mData == null || mData.isEmpty()) {
            return;
        }
        mData.remove(position);
        notifyItemRemoved(position);
        //删除数据后要进行刷新,否则下次删除的时候position会对应错误
       notifyDataSetChanged();
    }

然后在你需要的地方进行调用,我是在MainActivity中添加了两个按钮进行简单的添加和删除操作

 @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.add_btn:
                mRecycleAdapter.addNewItem();
                //回到第一个Item
                mLinearLayoutManager.scrollToPosition(0);
                break;
            case R.id.delete_btn:
                mRecycleAdapter.deleteItem();
                mLinearLayoutManager.scrollToPosition(0);
                break;
        }
    }

效果如下:
RecyclerView的简单使用

RecyclerView可以设置列表中Item删除和添加的动画,V7包中提供了一个默认动画,只需设置一下就可以了.

// 设置Item添加和移除的动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());

效果:
RecyclerView的简单使用

4.点击事件

RecyclerView并没有像ListView一样提供点击事件,需要自己自定义点击事件和长按事件.
通过在绑定ViewHolder的时候设置监听,然后通过Apater回调出去

在Adapter里创建一个监听器,并提供一个方法:

    interface OnItemClickListener {
        void onClick();
        void onLongClick();
    }

    //设置为全局变量
    private OnItemClickListener mOnItemClickListener;
    public void setItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
    }

然后对ViewHolder设置监听

 @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        Log.v("cherish233","onBindViewHolder:"+position);
        holder.mTx.setText(mData.get(position));

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOnItemClickListener.onClick(position);
            }
        });

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                mOnItemClickListener.onLongClick(position);
                return true;
            }
        });
    }

设置完监听后,就回到Activity,对Adapter设置监听,并实现方法

//设置点击事件
    private void setClickEvent() {
        mRecycleAdapter.setItemClickListener(new RecycleAdapter.OnItemClickListener() {
            @Override
            public void onClick() {
                Toast.makeText(getApplicationContext(),"我点击了一下",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLongClick() {
                Toast.makeText(getApplicationContext(),"我长按了item",Toast.LENGTH_SHORT).show();
            }
        });
    }

现在只是简单睇地介绍了一下,不仅不够完善,而且还有很多效果没有做出来,等有时间再好好研究下.