关于RecyclerView

本文详细介绍了RecyclerView的基本用法和高级特性,包括其与ListView的区别、多种布局管理器的应用、ItemView的控制及点击事件的处理。

1.概述:

RecyclerView的设计与ListView、GridView类似,也使用了Adapter,不过该Adapter并不是ListView中的Adapter,而是RecyclerView的一个静态内部类。该Adapter有一个泛型参数VH,代表的就是ViewHolder。RecyclerView还封装了一个ViewHolder类型,该类型中有一个itemView字段,代表的就是每一项数据的根视图,需要在构造函数中传递给ViewHolder对象。RecyclerView这么设计相当于将ListView的Adapter进行了再次封装,把getView函数中判断是否含有缓存的代码段封装到RecyclerView内部,使这部分逻辑对用户不可见。用户只需要告诉RecyclerView每项数据是怎么样的以及将数据绑定到每项数据上,分别对应的函数为onCreateViewHolder函数、onBindViewHolder函数,当然还需要通过getItemCount告诉RecyclerView有多少项数据,以往适用于ListView的 Adapter中的getView函数中的逻辑就不需要用户来处理了。

基本用法如下:


compile 'com.android.support:recyclerview-v7:25.3.1'
public class Fruit {
    private String name;
    private int imageId;
    public Fruit(String name,int imageId) {
        this.name = name;
        this.imageId = imageId;
    }
    public String getName() {
        return name;
    }
    public int getImageId() {
        return imageId;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:layout_width="wrap_content"
              android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/fruit_name"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> mFruLis;
    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(View vie) {
            super(vie);
            fruitImage = (ImageView) vie.findViewById(R.id.fruit_image);
            fruitName = (TextView) vie.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List<Fruit> fruLis) {
        mFruLis = fruLis;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup par,int vieTyp) {
        View vie = LayoutInflater.from(par.getContext()).inflate(R.layout.fruit_item,par,false);
        ViewHolder hol = new ViewHolder(vie);
        return hol;
    }

    @Override
    public void onBindViewHolder(ViewHolder hol,int pos) {
        Fruit fru = mFruLis.get(pos);
        hol.fruitImage.setImageResource(fru.getImageId());
        hol.fruitName.setText(fru.getName());
    }

    @Override
    public int getItemCount() {
        return mFruLis.size();
    }
}
<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_height="match_parent"
    android:layout_width="match_parent" />
private List<Fruit> fruLis = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initFruits();
    RecyclerView recVie = (RecyclerView) findViewById(R.id.recycler_view);
    LinearLayoutManager layMan = new LinearLayoutManager(this);
    recVie.setLayoutManager(layMan);
    FruitAdapter ada = new FruitAdapter(fruLis);
    recVie.setAdapter(ada);
}

private void initFruits() {
    for(int i=0;i<3;i++) {
        Fruit at = new Fruit("apple",R.drawable.at);
        fruLis.add(at);
        Fruit camera = new Fruit("apple",R.drawable.camera);
        fruLis.add(camera);
        Fruit clock = new Fruit("apple",R.drawable.clock);
        fruLis.add(clock);
        Fruit movie = new Fruit("apple",R.drawable.movie);
        fruLis.add(movie);
        Fruit music = new Fruit("apple",R.drawable.music);
        fruLis.add(music);
        Fruit right = new Fruit("apple",R.drawable.right);
        fruLis.add(right);
    }
}


2.高级用法

RecyclerView的另一大特点就是将布局方式抽象为LayoutManager,默认提供了LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager 3种布局,对应为线性布局、网格布局、交错网格布局,如果这些都无法满足你的需求,你还可以定制布局管理器实现特定的布局方式。

RecyclerView通过桥接的方式将布局职责抽离出去,使得RecyclerView变得更灵活。例如,如果用户只需要修改RecyclerView的布局方式,只需要修改LayoutManager即可,而不需要操作复杂的RecyclerView类型。而ListView、GridView正好是相反的,它们只是布局方式不一样,但却是两个类型,它们覆写了基类AbsListView的layoutChildren函数来实现不同的布局。显然,通过组合的形式要好于通过继承,因此,RecyclerView在设计上也要好于AbsListView类族。

除此之外,RecyclerView对于Item View的控制也更为精细,可以通过ItemDecotation为Item View添加装饰,也就是在Item View上进行二次加工;又可以用过ItemAnimator为Item View添加动画。


实现横向滚动:

fruit_item.xml 把布局改为垂直方向

MainActivity添加如下代码:

layMan.setOrientation(LinearLayoutManager.HORIZONTAL);


点击事件:

修改FruitAdapter代碼如下:

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> mFruLis;
    static class ViewHolder extends RecyclerView.ViewHolder {
        View fruitView;
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(View vie) {
            super(vie);
            fruitView = vie;
            fruitImage = (ImageView) vie.findViewById(R.id.fruit_image);
            fruitName = (TextView) vie.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List<Fruit> fruLis) {
        mFruLis = fruLis;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup par,int vieTyp) {
        View vie = LayoutInflater.from(par.getContext()).inflate(R.layout.fruit_item,par,false);
        final ViewHolder hol = new ViewHolder(vie);
        hol.fruitView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = hol.getAdapterPosition();
                Fruit fru = mFruLis.get(pos);
                Toast.makeText(v.getContext(),"you clicked view" + fru.getName(),Toast.LENGTH_SHORT).show();
            }
        });
        hol.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = hol.getAdapterPosition();
                Fruit fru = mFruLis.get(pos);
                Toast.makeText(v.getContext(),"you clicked image" + fru.getName(),Toast.LENGTH_SHORT).show();
            }
        });
        return hol;
    }

    @Override
    public void onBindViewHolder(ViewHolder hol,int pos) {
        Fruit fru = mFruLis.get(pos);
        hol.fruitImage.setImageResource(fru.getImageId());
        hol.fruitName.setText(fru.getName());
    }

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












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值