Android5.0 v7扩展包之RecyclerView

Android5.0 v7扩展包之RecyclerView

Android开发文章 androidRecyclerView

近日Google发布了Android5.0 SDK,随之android L的部分预览功能也发布了正式版本。本文将介绍RecyclerView

RecylerView简介

The RecyclerView widget is a more advanced and flexible version of ListView. This widget is aContainer
for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerView widget when you have data collections whose elements change at runtime based on user action or network events.

大意是RecylerView是一个高级的ListView。可以很好的维护大数据集的滚动和显示。详细的解释参考这里。本文的内容也是基于此而写。

RecylerView在那里

  • 包名:android.support.v7.widget.RecyclerView
  • 文件地址有两个
    • 1:android-sdk/extras/android/m2repository/com/android/support/recyclerview-v7
    • 2:android-sdk/extras/android/support/v7/recyclerview

RecylerView怎么引用

Android Studio

<span style="font-size:18px;">dependencies {
    compile 'com.android.support:recyclerview-v7:21.0.0'
}</span>

在此推荐使用Android
Studio
开发Android项目

Eclipse

以下猜测可以使用,没有经过测试。

  • android-sdk/extras/android/support/v7/recyclerview目录下面有libs,里面有jar包,引用此jar包。
  • android-sdk/extras/android/m2repository/com/android/support/recyclerview-v7目录下根据版本号21.0.0目录可以找到一个名为recyclerview-v7-21.0.0.aar的文件。解压此文件里面有classes.jar,引用此jar包。

找不到目录

针对找不到目录的同学,打开Android SDK Manager把最新的资源更新下来即可。

RecylerView新类介绍

说说几个新类,Adapter(android.support.v7.widget.RecyclerView.Adapter)ViewHolder(android.support.v7.widget.RecyclerView.ViewHolder)LayoutManager(android.support.v7.widget.RecyclerView.LayoutManager)

Adapter

适配器,和以前的Adapter不一样,此Adapter为RecylerView特有。作为一个抽象类,有以下几个抽象方法。

public static abstract class Adapter<VH extends ViewHolder>{}{
    ...
    public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
    public abstract void onBindViewHolder(VH holder, int position);
    public abstract int getItemCount();
    ...
}
方法onCreateViewHolder

直接创建一种可复用的VH或者根据viewType创建多种VH

方法onBindViewHolder

数据和VH通过位置position绑定

方法getItemCount

返回有多少条数据

ViewHolder

同样是一个抽象类,我们通过继承此类实现view的封装。

LayoutManager

布局管理器,RecylerView中数据显示布局方式。目前v7包种提供了三种模式,分别是LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager

LinearLayoutManager

线性布局,通过方向VERTICALHORIZONTAL可以实现垂直和水平的效果。默认为VERTICAL垂直方向。

通过此布局可以实现ListView的效果。垂直方向为普通的ListView显示效果,水平方向即是水平滑动的ListView

GridLayoutManager

网格布局,继承于LinearLayoutManager,可以指定有几行和方向。

通过此布局可以实现GridView的效果,同样有垂直方向和水平方向。

StaggeredGridLayoutManager

交错网格布局,类似于网格布局,但每个格子的高度或者长度可以不一样。

俗称的瀑布流效果,同样有垂直方向和水平方向。

实例代码

实例代码会列出一个完整的通过RecylerViewLinearLayoutManagerAdapterViewHolder实现一个普通的ListView数据显示效果,之后修改部分代码实现不同的效果。

ListView

引入的包
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.0'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
    compile 'com.android.support:recyclerview-v7:21.0.0'
    compile 'org.roboguice:roboguice:2.0'
    compile 'com.android.support:palette-v7:21.0.0'
}
Activity

package com.lizheng.recylerviewdemo;

import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;

import roboguice.activity.RoboFragmentActivity;
import roboguice.inject.InjectView;

public class MainActivity extends RoboFragmentActivity {

    @InjectView(R.id.recyclerView)
    private RecyclerView recyclerView;

    @InjectView(R.id.swipeLayout)
    private SwipeRefreshLayout swipeLayout;

    private DemoAdapter adapter;

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

        adapter = new DemoAdapter(C.picUrls);

        // 线性布局管理器
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);

        // 设置布局管理器
        recyclerView.setLayoutManager(linearLayoutManager);

        recyclerView.setAdapter(adapter);

        // 模拟下拉刷新
        swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeLayout.setRefreshing(false);
                        adapter.notifyDataSetChanged();
                    }
                }, 2000);
            }
        });

    }

}
AdapterViewHolder

package com.lizheng.recylerviewdemo;

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.nostra13.universalimageloader.core.ImageLoader;

/**
 * 适配器
 * Created by lizheng on 14/10/19.
 */
public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.DemoViewHolder> {
    String[] picUrls;

    public DemoAdapter(String[] picUrls) {
        this.picUrls = picUrls;
    }

    @Override
    public DemoViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        // 加载数据item的布局,生成VH返回
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_test, viewGroup, false);
        return new DemoViewHolder(v);
    }

    @Override
    public void onBindViewHolder(DemoViewHolder demoViewHolder, int i) {
        // 数据绑定
        ImageLoader.getInstance().displayImage(picUrls[i], demoViewHolder.imavPic);
        demoViewHolder.tvUrl.setText(picUrls[i]);
    }

    @Override
    public int getItemCount() {
        // 返回数据有多少条
        if (null == picUrls) {
            return 0;
        }
        return picUrls.length;
    }

    // 可复用的VH
    public static class DemoViewHolder extends RecyclerView.ViewHolder {
        // 大图
        public ImageView imavPic;
        // 图片url
        public TextView tvUrl;

        public DemoViewHolder(View itemView) {
            super(itemView);
            imavPic = (ImageView) itemView.findViewById(R.id.imavPic);
            tvUrl = (TextView) itemView.findViewById(R.id.tvUrl);
        }
    }
}
Activity布局
<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"
    tools:context=".MainActivity">

    <View
        android:background="#FFFFFF"
        android:id="@+id/vTestPalette"
        android:layout_width="match_parent"
        android:layout_height="48dp" />

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeLayout"
        android:layout_below="@id/vTestPalette"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical" />
    </android.support.v4.widget.SwipeRefreshLayout>

</RelativeLayout>

item布局
<?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:layout_margin="5dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imavPic"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/tvUrl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:lines="2" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp" />
</LinearLayout>
效果图

横向的ListView

实现横向的ListView,修改线性布局管理器属性即可。

默认为

// 线性布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);

修改为

// 线性布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

要想横向的效果好一些,需要对item的布局做一些小修改

<ImageView
        android:id="@+id/imavPic"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:scaleType="centerCrop" />

改为

<ImageView
        android:id="@+id/imavPic"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:scaleType="centerCrop" />
效果图

GridView

实现此效果,更改布局管理器即可,并微调item的布局

// 线性布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

// 设置布局管理器
recyclerView.setLayoutManager(linearLayoutManager);

改为

// 网格布局管理器
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
gridLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// 设置布局管理器
recyclerView.setLayoutManager(gridLayoutManager);

item布局中

<ImageView
        android:id="@+id/imavPic"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:scaleType="centerCrop" />

改为

<ImageView
        android:id="@+id/imavPic"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:scaleType="centerCrop" />

通过可以修改方向、也可以修改行数。代码自己修改,下面直接显示效果图。注意修改方向要注意图片的宽度要适当,不建议使用match_parent

效果图1

效果图2

效果图3

瀑布流

实现瀑布流,修改布局管理器和item布局即可。

布局管理器
<span style="font-size:18px;">// 网格布局管理器
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
gridLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// 设置布局管理器
recyclerView.setLayoutManager(gridLayoutManager);</span>

改为

// 交错网格布局管理器
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
// 设置布局管理器
recyclerView.setLayoutManager(staggeredGridLayoutManager);
item布局

改为

<?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:layout_margin="5dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imavPic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/tvUrl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

同样可以修改为横向和行数,看效果即可。

效果图1

效果图2

效果图3

后记

RecylerView作为新出现的组件。还有很多的问题和用法期待大家的发现。

已知问题

  • StaggeredGridLayoutManager时图片会自动跳转
  • 没有可以直接使用的onItemClickListener
  • 没有直接使用的headViewfooterView

代码

时间: 2024-11-06 21:09:03

Android5.0 v7扩展包之RecyclerView的相关文章

Android 5.0 v7扩展包之RecyclerView的使用以及通用适配器的封装实现

添加Gradle依赖 compile 'com.android.support:appcompat-v7:23.2.1'compile 'com.android.support:recyclerview-v7:23.2.1' 备注:recyclerview的版本号要与appcompat的一致,此处为: v7:23.2.1 以泛型方式定义通用RecyclerViewHold对象,内部以SparseArray存储View对象,提高xml的解析速度. /** * Created by Administ

android v7兼容包RecyclerView的使用(二)

上篇文章 android v7兼容包RecyclerView的使用(一)讲了RecyclerView的最基本用法,现在开始挖掘更详细的内容. 在RecyclerView的API中,有这样一句话 A flexible view for providing a limited window into a large data set. 大致意思就是:当有大量的数据显示在一个有限大小的窗口上时,RecyclerView就是解决这种情况的一个灵活的View. 从以上描述可以看出RecyclerView的

android v7兼容包RecyclerView的使用(三)——布局管理器的使用

前两篇文章 android v7兼容包RecyclerView的使用(二) android v7兼容包RecyclerView的使用(一) 介绍了RecyclerView的基本用法以及与它相关的重要的几个类,本篇文章介绍布局管理器的具体用法. 为了演示布局管理器的使用,找了很多个例子,都没有找到感觉合适的例子,后来google了一把,发现了一个比较适合说明问题的例子.所以就拿该例子来解释吧. 在演示布局管理器前,我们先把UI部分搭建完成.由于使用到了V7兼容包的另一个包CardView,所以在这

Android5.0控件-RecyclerView

Android 5.0引入了一个全新的列表控件-RecyclerView,这个控件更为灵活,同时也拥有比ListView和GridView控件较多的优点:例如Item View的创建.View的回收以及重用等机制. RecyclerView控件提供了以下两种方法来进行简化和处理大数量集合: ?l 采用LayoutManager来处理Item的布局 ?l 提供Item操作的默认动画,例如在增加或者删除item的时候 可以自定义LayoutManager或者设置添加/删除的动画,整体的Recycle

Android5.0新特性:RecyclerView实现上拉加载更多

RecyclerView是Android5.0以后推出的新控件,相比于ListView可定制性更大,大有取代ListView之势.下面这篇博客主要来实现RecyclerView的上拉加载更多功能. 基本思路是让RecyclerView的Adapter加载两种布局,第一个布局来显示主界面,第二个布局来显示上拉加载时的提示信息,让RecyclerView监听是否滑动到最后一个item,如果是,则调用上拉刷新的逻辑,拉取远程数据,并显示第二个布局.等加载完毕时,刷新 Adapter,并隐藏第二个布局.

android v7兼容包RecyclerView的使用(四)——点击事件的不同方式处理

前三篇文章 android v7兼容包RecyclerView的使用(三)--布局管理器的使用 android v7兼容包RecyclerView的使用(二) android v7兼容包RecyclerView的使用(一) 介绍了RecyclerView的使用以及常见的相关类和布局管理器的灵活之处.写了这么多篇,还没涉及到用户交互,那么怎么处理点击事件呢. 在RecyclerView中你会惊奇的发现,该类中并没有OnItemClickListener监听器监听我们的单击事件,也没有OnItemL

一个Activity掌握Android5.0新控件 (转)

原文地址:http://blog.csdn.net/lavor_zl/article/details/51279386 谷歌在推出Android5.0的同时推出了一些新控件,Android5.0中最常用的新控件有下面5种. 1. CardView(卡片视图) CardView顾名思义是卡片视图,它继承FrameLayout.它是一个带圆角的背景和阴影FrameLayout.CardView被包装为一种布局,并且经常在ListView和RecyclerView的Item布局中,作为容器使用. Ca

Android5.0美不胜收的新特性 Material Design

Google提出了全新的设计规范Material Design,扁平化的设计,加上明亮的色彩,有一种美不胜收的感觉. Material Design翻译过来叫做"材料设计",Material Design是多种元素组合在一起形成一个层次的效果,有主题.新的控件.动画,那么使用Material Design要注意些什么呢?下面来看看使用的注意点: 1.保证兼容性,可以兼容市场占有率高的低版本系统 下面来初步认识一下Material Design的设计规范: 1.使用Material De

Android5.0 新特性学习总结

参考文章: 极客学院 –Material Design 中文版图文教程 几行代码,让你的 APP 变得花俏-Android Design Support Library 代码实验 material design 的android开源代码整理 低版本android上实现Material design应用 Android5.0版本,推出了Material Design的概念,这是在设计上Android的又一大突破.对应的程序实现上就有如 Theme.Material.Light. Theme.Mat