Android开发笔记:RecyclerView(一)先学会使用

这篇博客详细介绍了Android开发中RecyclerView的基础使用,包括viewHolder、onCreateViewHolder、onBindViewHolder和getItemCount的方法。作者强调了ViewHolder在列表滚动时的复用机制,以及如何在Activity中设置RecyclerView。此外,还讲解了如何添加系统和自定义间隔,提供了自定义间隔的实现代码示例。

对RecyclerView一直处于一种朦胧的理解状态,最近项目经常使用RecyclerView,本系列主要从浅入深的总结自己对RecyclerView的理解


前言

       面对一个新控件,首先要学会使用,然后再逐步学习其原理,RecyclerView作为ListView 的替代,灵活性更强,我把它理解为一个插线板,需要什么功能就插入什么,非常方便。

      初学Android时,习惯于控件直接绑定内容,例如TextView,直接可以设置文字信息,对于ListView和RecyclerView这种展示大量数据的控件非常不理解,所以对控件的使用也非常不熟悉。使用控件时,我们主要会处理三个主体:Layout(View)、adapter、ItemModel。三个主体理解到位了,对于此类控件的使用变会的容易些。

Layout不用过多解释,要使用这类控件,一般最少要涉及2个layout,一个作为Activity的Layout,一个作为列表Item的layout

ItemModel,可以把他看做数据,即每个列表要展示的内容。

adapter就是将内容绑定到view 的工具。可以理解为MVC模式

 

RecyclerView的使用

首先再Android studio中导入RecyclerView,网上有一万种方法,读者可以自行查阅。

导入RecyclerView后,便要创建上面说的三种主体,首先是Layout,创建一个Activity的Layout,如下,Activity中只包含了一个RecyclerView。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.recyclerviewt.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/RVContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

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

</android.support.constraint.ConstraintLayout>

另外一个Layout为RecyclerView每一个列表的视图,本文每个Item显示一个数字,所以界面只包含了一个TextView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/view_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="40sp"
        android:gravity="center"
        />

</LinearLayout>

然后创建adapter继承RecyclerView.Adapter, 需要重写三个方法,分别是onCreateViewHolder、onBindViewHolder、getItemCount

viewHolder

ViewHolder可以理解为一个View的容器,列表在滚动的时候,为了避免不断的findViewByID影响效率,将view存放在ViewHolder中进行复用,例如每页展示7个Items,当向上滑动时,item1划出界面,就可以将item的viewholder复用,更新为下方可见的item内容,避免不断的findViewByID

public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public ViewHolder(View itemView) {
            super(itemView);
            textView = (TextView)itemView.findViewById(R.id.view_text);
        }
    }

onCreateViewHolder

onCreateViewHolder的作用就是创建ViewHolder,在列表刚打开时,由于之前没有创建过ViewHolder,无法复用,所以需要重新创建,新建一个item的view,放到ViewHolder容器中。

public MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item_view,parent,false);
        MyAdapter.ViewHolder viewHolder = new MyAdapter.ViewHolder(view);
        return viewHolder;
    }

onBindViewHolder

上面讲了每个ViewHolder在复用时需要更新里面View的内容,相当于把新的View内容与VIewHolder连接起来,所以每次需要在ViewHolder中更新view时都会调用这个方法

@Override
    public void onBindViewHolder(@NonNull MyAdapter.ViewHolder holder, int position) {
        holder.textView.setText(Items.get(position).toString());
    }

adapter创建好后,需要准备ItemModel,本文每个列表只显示数字,所以不需要新建数据结构,只是生成了20个数字。

Activity

和其他控件一样,在使用时需要在Activity中进行绑定,对于RecyclerView需要设置其排列方向、动画、以及与adapter进行绑定,完整的Activity如下:



public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private MyAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager ;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initRV();
    }

    private void initRV(){
        mAdapter = new MyAdapter(initData());
        mLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
        mRecyclerView = (RecyclerView) findViewById(R.id.RVContent);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.HORIZONTAL));
    }

    private ArrayList<Integer> initData(){
        ArrayList<Integer> data = new ArrayList<>();
        for(int i=0;i<20;i++){
            data.add(i);
        }
        return data;
    }
}

我调整了TextView的宽高和颜色,并设置排列方式为水平排列,效果如下:

设置间隔

RecyclerView和ListView不同,为了保证RecyclerView的灵活性,item之间的间隔的设计也独立了出来,通过调用adapter的addItemDecortion方法添加间隔。

1.系统自带的间隔线:

addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL))

2.自定义间隔

系统自带的分割线是通过DividerItemDecoration类进行实现的,查看源码可以看到,这个类是通过继承RecyclerView.ItemDecoration实现间隔的样式:

public class DividerItemDecoration extends ItemDecoration

我们也可以通过继承来实现自己的间隔,需要重写onDraw和getItemOffsets方法,onDraw主要实现我们要在间隔中绘制的内容,getItemOffsets用来设置每个Item周围的间隔大小,本文自定义一种空白间隔,不绘制内容,第一个和最后一个item的两边间距50,中间的item间距12,自定义ItemDecoration如下:

class mItemDecoration extends RecyclerView.ItemDecoration{
        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) parent.getLayoutManager();
            Context context = MainActivity.this;
            if(parent.getChildAdapterPosition(view) == 0){
                outRect.left = dip2px(context,50);
                outRect.right = dip2px(context,12);
            } else if(parent.getChildAdapterPosition(view) == linearLayoutManager.getItemCount()-1){
                outRect.right = dip2px(context,50);
                outRect.left = dip2px(context,12);
            } else{
                outRect.left = dip2px(context,12);
                outRect.right = dip2px(context,12);
            }
        }

    }

不绘制内容,所以没有重写onDraw方法,需要间隔,所以只重写了getItemOffsets方法,方法中outRect表示每个Item外围的宽度,默认为0,通过getChildAdapterPosition()方法可以得到当前绘制的间隔是哪个Item的。recyclerView设置为自定义的间隔效果如下:

这样一个简单的RecyclerVIew的使用就完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值