增强版ListView-RecyclerView

RecyclerView

本文参考郭霖《第一行代码》第2版

Recycyler不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不足之处(性能不好,扩展性差,只能纵向滚动)。目前Android官方更加推荐使用RecyclerView,未来也会有更多的程序逐渐从ListView转向RecyclerView。

依赖库

RecyclerView定义在support库中,需要在项目module的build.gradle中添加相应的依赖库:
com.android.support:recyclerview-v7:25.0.1

app/build.gradle

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile project(':libzxing')
    compile files('libs/volley.jar')
    compile project(':slibrary')
    compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.android.support:design:25.0.1'
    compile 'com.android.support:support-v13:25.0.1'
    compile 'com.android.support:support-v4:25.0.1'
    compile files('libs/jackson/jackson-annotations-2.8.0.jar')
    compile files('libs/jackson/jackson-core-2.8.1.jar')
    compile files('libs/jackson/jackson-databind-2.8.1.jar')
    compile 'com.android.support:recyclerview-v7:25.0.1'
}

RecycleView实现ListView的功能

  • 新建一个Java Bean类Christmas.java,作为Adapter的适配类型。
package com.silion.androidproject.recycleview;

/**
 * Created by silion on 2016/12/29.
 */

public class Christmas {
    private String mName; //名字
    private int mImageId; //图片ID

    public Christmas(String name, int imageId) {
        mName = name;
        mImageId = imageId;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public int getImageId() {
        return mImageId;
    }

    public void setImageId(int imageId) {
        mImageId = imageId;
    }

    @Override
    public String toString() {
        return "Christmas{" +
                "mName='" + mName + '\'' +
                ", mImageId=" + mImageId +
                '}';
    }
}
  • 在layout目录新建Item的布局listitem_christmas_vertical.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:paddingTop="5dp"
              android:paddingBottom="5dp"
              android:paddingLeft="10dp"
              android:paddingRight="5dp"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

    <ImageView
        android:id="@+id/iconImageView"
        android:layout_width="40dp"
        android:layout_height="40dp"
        tools:src="@drawable/christmas_santa"/>

    <TextView
        android:id="@+id/titleTextView"
        android:layout_marginLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textSize="22sp"
        tools:text="圣诞老人"/>
</LinearLayout>

这里写图片描述

  • 新建自定义的ChristmasVerticalAdapter,这个Adapter继承于RecyclerView.Adapter,主要有4个点:
    1. 新建一个内部类ViewHolder继承于RecyclerView.ViewHolder,并作为Adapter的泛型类型。主要是用来缓存View,减少findViewById的开销
    2. 重写getItemCount()方法,RecyclerView Item的数量,直接返回数据list的size
    3. 重写onCreateViewHolder()方法,在这个方法中将listitem_christmas_vertical布局inflate进来,并且作为参数创建ViewHolder,创建的ViewHolder会自动实现之后重用,也就是说并不是所有的item都需要创建ViewHolder,点击事件一般也是在这里注册
    4. 重写onBindViewHolder()方法,该方法用于对RecyclerView item的数据进行赋值,会在每个item被滚动到屏幕内的时候执行
package com.silion.androidproject.recycleview;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.silion.androidproject.R;

import java.util.List;

/**
 * Created by silion on 2016/12/29.
 */

public class ChristmasVerticalAdapter extends RecyclerView.Adapter<ChristmasVerticalAdapter.ViewHolder> {
    List<Christmas> mChristmasList;

    public ChristmasVerticalAdapter(List<Christmas> christmasList) {
        mChristmasList = christmasList;
    }

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

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Christmas christmas = mChristmasList.get(position);
        holder.mIconImageView.setImageResource(christmas.getImageId());
        holder.mTitleTextView.setText(christmas.getName());
    }

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

    static class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView mIconImageView;
        public TextView mTitleTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            mIconImageView = (ImageView) itemView.findViewById(R.id.iconImageView);
            mTitleTextView = (TextView) itemView.findViewById(R.id.titleTextView);
        }
    }
}
  • 在布局中加入RecyclerView,和加入ListView类似,但RecyclerView并不是内置在系统SDK中,所以需要把完整的包路径写出来。
<?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"
              android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
  • 在代码中使用RecyclerView,必选的有5点

    1. 通过findViewById获取在布局中添加的RecyclerView实例
    2. 新建Adapter实例,数据list作为构造方法的参数
    3. 新建LayoutManager实例,这里使用LinearLayoutManager,默认方向是vertical
    4. 给RecyclerView设置LayoutManager
    5. 给RecyclerView设置Adapter

    默认的RecyclerView是没有像ListView那样的分割线的,如果需要,可以通过继承RecyclerView.ItemDecoration实现自定义的分割线。
    在v7:25.0.1的RecyclerView包Android也已经给我们实现了和ListView的divider一样效果的分割线DividerItemDecoration。

mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
mChristmasAdapter = new ChristmasVerticalAdapter(((RecyclerViewActivity) getActivity()).getChristmas());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mChristmasAdapter);

// 在v7:25.0.1的RecyclerView包Android实现的DividerItemDecoration
DividerItemDecoration decoration = new DividerItemDecoration(mContext, LinearLayoutManager.VERTICAL);
// 默认是android.R.attr.listDivier样式,可以通过setDrawable设置自定义的divider样式
decoration.setDrawable(mContext.getDrawable(R.drawable.recycler_view_divider));
mRecyclerView.addItemDecoration(decoration);

效果图
这里写图片描述

RecycleView实现横向滚动功能

  • 新建一个Java Bean类Christmas.java,作为Adapter的适配类型。

  • 在layout目录新建Item的布局listitem_christmas_horizontal.xml,因为是横向滚动,所以把Item的布局改成纵向

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="100dp"
              android:padding="5dp"
              android:layout_height="100dp">

    <ImageView
        android:id="@+id/iconImageView"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center"
        tools:src="@drawable/christmas_santa"/>

    <TextView
        android:id="@+id/titleTextView"
        android:layout_marginTop="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textSize="22sp"
        tools:text="圣诞老人"/>
</LinearLayout>

这里写图片描述

  • 新建自定义的ChristmasHorizontalAdapter,这个Adapter继承于RecyclerView.Adapter,在onCreateViewHolder方法将listitem_christmas_horizontal布局inflate进来作为构造方法创建ViewHolder实例
    @Override
    public ChristmasHorizontalAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_christmas_horizontal, parent, false);
        ChristmasHorizontalAdapter.ViewHolder viewHolder = new ChristmasHorizontalAdapter.ViewHolder(view);
        return viewHolder;
    }
  • 在布局中加入RecyclerView

  • 在代码中使用RecyclerView,LayoutManager还是用LinearLayoutManager,但是设置方向为横向,divider使用listview默认的样式

RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
ChristmasHorizontalAdapter christmasAdapter = new ChristmasHorizontalAdapter(((RecyclerViewActivity) getActivity()).getChristmas());
LinearLayoutManager layoutManager = new LinearLayoutManager(mContext);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager); // 设置为横向
recyclerView.addItemDecoration(new DividerItemDecoration(mContext, LinearLayoutManager.HORIZONTAL));
recyclerView.setAdapter(christmasAdapter);

效果图
这里写图片描述

RecycleView实现瀑布流布局

  • 新建一个Java Bean类Christmas.java,作为Adapter的适配类型。

  • 在layout目录新建Item的布局listitem_christmas_staggered_grid.xml,这里使用RelativeLayout包住LinearLayout将图片和标题放在中间

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


    <LinearLayout
        android:layout_width="wrap_content"

        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/iconImageView"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            tools:src="@drawable/christmas_santa"/>

        <TextView
            android:id="@+id/titleTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="5dp"
            android:textSize="22sp"
            tools:text="圣诞老人"/>
    </LinearLayout>
</RelativeLayout>

这里写图片描述

  • 新建自定义的ChristmasHorizontalAdapter,这个Adapter继承于RecyclerView.Adapter
    1.在onCreateViewHolder方法将listitem_christmas_staggered_grid布局inflate进来作为构造方法创建ViewHolder实例,并注册点击事件监听
    2.瀑布流布局需要各个Item的高度不一致才能看的出效果,所以将每个Item的高度设为随机值
    @Override
    public ChristmasStaggeredGridApdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_christmas_staggered_grid, parent, false);
        StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
        params.height = getRandomHeight(); //高度设为随机值
        final ChristmasStaggeredGridApdapter.ViewHolder viewHolder = new ChristmasStaggeredGridApdapter.ViewHolder(view);
        // 给Item设置点击事件监听
        viewHolder.mItemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = viewHolder.getAdapterPosition();
                Christmas christmas = mChristmasList.get(position);
                Toast.makeText(view.getContext(), "点击了" + christmas.getName() + "Item", Toast.LENGTH_SHORT).show();
            }
        });
        // 给Icon设置点击事件监听
        viewHolder.mIconImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = viewHolder.getAdapterPosition();
                Christmas christmas = mChristmasList.get(position);
                Toast.makeText(view.getContext(), "点击了" + christmas.getName() + "Iamge", Toast.LENGTH_SHORT).show();
            }
        });
        return viewHolder;
    }
  • 在布局中加入RecyclerView

  • 在代码中使用RecyclerView
    1.LayoutManager使用StaggeredGridLayoutManager,构造函数接收2个参数,第一个参数用于指定布局的列数,第二个参数用于指定布局的排列方向

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);
        RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        ChristmasStaggeredGridApdapter christmasAdapter = new ChristmasStaggeredGridApdapter(((RecyclerViewActivity) getActivity()).getChristmas());
        recyclerView.setAdapter(christmasAdapter);
        return rootView;
    }

效果图
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值