您的位置:首页 > 移动开发 > Android开发

Android5.0 v7扩展包之RecyclerView

2016-05-16 15:21 531 查看


Android5.0 v7扩展包之RecyclerView

Android开发文章
android
RecyclerView


近日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包种提供了三种模式,分别是
LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager


LinearLayoutManager


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

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


GridLayoutManager


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

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

StaggeredGridLayoutManager


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

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


实例代码

实例代码会列出一个完整的通过
RecylerView
LinearLayoutManager
Adapter
ViewHolder
实现一个普通的
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);
}
});

}

}



Adapter
ViewHolder

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

没有直接使用的
headView
footerView



代码

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: