去年google的IO上就展示了一个新的ListView。它就是RecyclerView。

下面是官方的说明,我英语能力有限,只是我大概这么理解:RecyclerView会比ListView更具有拓展性,使用更有效率,并且更灵活了,详细怎么样,时隔一年,我们也发现了它越来越强大,所以有必要去认识一下这个小伙伴了。

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

The RecyclerView class simplifies
the display and handling of large data sets by providing:

  • Layout managers for positioning items
  • Default animations for common item operations, such as removal or addition of items

You also have the flexibility to define custom layout managers and animations for RecyclerView widgets.

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

我们能够在最新版本号的support-v7上找到这个玩意儿。本文在v21上找到这个jar的:sdk\extras\android\m2repository\com\android\support\recyclerview-v7\21.0.0。在文件夹下将recyclerview-v7-21.0.0.aar解压。取出classes.jar,你能够更名为:android-support-v7-recyclerview.jar。至少我是这么干的

好了,进入这次demo的主题

1.demo结构

2.演示样例效果图

3.让我们边看代码边了解一下,这个控件吧。首先在界面布局文件里引入这个组件:

activity_main.xml

<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="${relativePackage}.${activityClass}" > <LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:checkedButton="@+id/linearlayout_rb"
android:gravity="center_horizontal"
android:orientation="horizontal" > <RadioButton
android:id="@+id/linearlayout_rb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/linearlayout" /> <RadioButton
android:id="@+id/gridlayout_rb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/gridlayout" />
</RadioGroup>
<span style="white-space:pre"> </span>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout> </RelativeLayout>

4.以下就是怎么使用它。这边就是简单的用法,在代码上我已经加上了凝视,简单理解一下吧。

MainActivity.java

package org.jan.components.demo;

import java.util.ArrayList;

import org.jan.components.demo.CustomAdapter.OnItemPressedListener;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.RecyclerListener;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RadioButton;
import android.widget.Toast;
/**
* android recyclerView的简单实例代码
* @author jan
*/
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private static final String KEY_LAYOUT_MANAGER = "layoutManager";
private enum LayoutManagerType {
GRID_LAYOUT_MANAGER, LINEAR_LAYOUT_MANAGER
} private RadioButton mLinearlayoutButton;
private RadioButton mGridLayoutButton; private RecyclerView mRecyclerView;
private CustomAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private LayoutManagerType mCurrentLayoutManagerType;
//建立的模拟数据
private ArrayList<String> mDataList;
//网格布局中的设置列数
private static int SpanCount=3;
//模拟数据的个数
private static int DataSize = 100; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDatas();
initViews(savedInstanceState);
} private void initViews(Bundle savedInstanceState) {
mLinearlayoutButton = (RadioButton) findViewById(R.id.linearlayout_rb);
mLinearlayoutButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setRecyclerViewManagerType(LayoutManagerType.LINEAR_LAYOUT_MANAGER);
}
});
mGridLayoutButton = (RadioButton) findViewById(R.id.gridlayout_rb);
mGridLayoutButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setRecyclerViewManagerType(LayoutManagerType.GRID_LAYOUT_MANAGER);
}
});
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
if(savedInstanceState!=null){
mCurrentLayoutManagerType = (LayoutManagerType) savedInstanceState
.getSerializable(KEY_LAYOUT_MANAGER);
Log.i(TAG, "mCurrentLayoutManagerType="+mCurrentLayoutManagerType);
} mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
setRecyclerViewManagerType(mCurrentLayoutManagerType);
mAdapter = new CustomAdapter(mDataList);
mRecyclerView.setAdapter(mAdapter);
//设置recycler拥有固定的大小,提高展示效率
mRecyclerView.setHasFixedSize(true);
//设置默认的动画,在移除和加入的效果下展现,如今github上能够找到很多拓展。有兴趣的能够找找
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//实现我们给Adapter监听的方法,由于recyclerview没有Listview的OnClick和OnlongClick类似的方法
mAdapter.setOnItemPressedListener(new OnItemPressedListener() {
@Override
public void onItemClick(int position) {
Toast.makeText(MainActivity.this, "你点击了 item-"+mDataList.get(position), Toast.LENGTH_SHORT).show();
} @Override
public boolean OnItemLongClick(int position) {
//这里模拟了删除的功能
removeItemByPosition(position);
// insertItemByPosition(position);
Toast.makeText(MainActivity.this, "你长按了 item-"+mDataList.get(position), Toast.LENGTH_SHORT).show();
return true;
}
});
mRecyclerView.setRecyclerListener(new RecyclerListener() {
//资源回收后被调用
@Override
public void onViewRecycled(ViewHolder viewHolder) {
CustomAdapter.ViewHolder vh = (org.jan.components.demo.CustomAdapter.ViewHolder) viewHolder;
Log.d(TAG, "onViewRecycled->"+vh.getItemText().getText());
}
});
} //创建模拟的数据
private void initDatas() {
mDataList = new ArrayList<String>();
for (int i = 0; i < DataSize; i++) {
mDataList.add(String.format(getString(R.string.iamstudent), i));
}
}
/**
* 能够改变recycler的布局显示方式
* @param type
*/
protected void setRecyclerViewManagerType(LayoutManagerType type) {
int scrollPosition = 0;
if (mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView
.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
switch (type) {
//网状
case GRID_LAYOUT_MANAGER:
mLayoutManager = new GridLayoutManager(this, SpanCount);
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;
break;
//线性,如list
case LINEAR_LAYOUT_MANAGER:
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.canScrollHorizontally();
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
break;
default:
mLayoutManager = new LinearLayoutManager(this);
mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
break;
}
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(scrollPosition);
} /**
* 通过RecyclerView的adapter来移除指定位置的数据
* @param position
*/
protected void removeItemByPosition(int position) {
if(mAdapter!=null&&position>0){
mAdapter.notifyItemRemoved(position);
mDataList.remove(position);
mAdapter.notifyItemRangeChanged(position, mAdapter.getItemCount());
//你假设用了这个 ,就没有动画效果了。 // mAdapter.notifyDataSetChanged();
}
}
//相应这是能够新增指定索引的
protected void insertItemByPosition(int position) {
if(mAdapter!=null&&position>0){
mAdapter.notifyItemInserted(position);
mDataList.add(position, String.format(getString(R.string.iamstudent), position));
mAdapter.notifyItemRangeChanged(position, mAdapter.getItemCount());
}
} @Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable(KEY_LAYOUT_MANAGER, mCurrentLayoutManagerType);
super.onSaveInstanceState(outState);
} @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
} }

5.这个customAdapter是实现了RecyclerView.Adapter,当中的ViewHolder貌似是给我们自定义的,我没看过源代码,但我的直觉告诉我他一定是优化了ListView对viewholder的反复利用。

package org.jan.components.demo;

import java.util.List;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; public class CustomAdapter extends
RecyclerView.Adapter<CustomAdapter.ViewHolder> { private List<String> dataList; private OnItemPressedListener onItemPressedListener; public CustomAdapter(List<String> data) {
this.dataList = data;
} @Override
public int getItemCount() {
return dataList.size();
}
//替换视图内的内容
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.getDrawableId().setBackgroundResource(R.drawable.school_student);
viewHolder.getItemText().setText(dataList.get(position));
}
//由RecyclerView的Layout manager来生成一个新的ViewHolder
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.layout_row_item, viewGroup, false);
return new ViewHolder(v);
}
/**
* 继承RecyclerView的ViewHolder来自己定义一个视图内的ViewHolder
*/
public class ViewHolder extends RecyclerView.ViewHolder { private ImageView drawableId;
private TextView itemText; public ViewHolder(View itemView) {
super(itemView);
if(itemView!=null){
//这里我为这个View加入了点击和长按事件的监听绑定。为了使本demo更像一个listView
itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(onItemPressedListener!=null){
onItemPressedListener.onItemClick(getPosition());
}
}
});
itemView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(onItemPressedListener!=null){
return onItemPressedListener.OnItemLongClick(getPosition());
}
return false;
}
});
drawableId = (ImageView) itemView.findViewById(R.id.item_image);
itemText = (TextView) itemView.findViewById(R.id.item_text);
}
} public ImageView getDrawableId() {
return drawableId;
} public TextView getItemText() {
return itemText;
}
} public void setOnItemPressedListener(
OnItemPressedListener onItemPressedListener) {
this.onItemPressedListener = onItemPressedListener;
} protected static interface OnItemPressedListener{
void onItemClick(int position);
boolean OnItemLongClick(int position);
}
}

好,代码都讲的非常清楚简洁,主要是为了添加对RecyclerView的认识,如今非常多新的app,都已经加入了这组件。非常多大牛也写了对他的强大的拓展。

我在这里也加入一个有进阶性的博文。可供你我有时间学习

Android RecyclerView 使用全然解析 体验艺术般的控件

[Android]使用RecyclerView替代ListView(二)

[Android]RecyclerView的简单演示样例的更多相关文章

  1. Android通过startService播放背景音乐简单演示样例

    关于startService的基本使用概述及其生命周期可參见博客<Android中startService的使用及Service生命周期>. 本文通过播放背景音乐的简单演示样例,演示sta ...

  2. Introspector(内省)简单演示样例 与 简单应用

    简单演示样例: package com.asdfLeftHand.test; import java.beans.BeanDescriptor; import java.beans.BeanInfo; ...

  3. JBoss 系列九十六:JBoss MSC - 简介及一个简单演示样例

    什么是 JBoss MSC JBoss MSC 即 JBoss Modular Service Container,是第三代 JBoss 产品 JBoss 7和WildFfly的内核,JBoss MS ...

  4. Thrift的安装和简单演示样例

    本文仅仅是简单的解说Thrift开源框架的安装和简单使用演示样例.对于具体的解说,后面在进行阐述. Thrift简述                                           ...

  5. [hadoop系列]Pig的安装和简单演示样例

    inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) Pig是Yaho ...

  6. 一则简单演示样例看Oracle的“无私”健壮性

    Oracle的强大之处就在于他能总帮助让你选择正确的运行计划,即使你给了它错误的指示. 实验: 1. 创建測试表: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  7. 百度地图 Android SDK - 检索功能使用的简单演示样例

    百度地图 SDK 不仅为广大开发人员提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发人员提供了多种 LBS 检索的能力. 通过这些接口,开发人员能够轻松的訪问百度的 LBS 数据,丰富自己的移 ...

  8. android listview综合使用演示样例_结合数据库操作和listitem单击长按等事件处理

    本演示样例说明: 1.自己定义listview条目样式,自己定义listview显示列数的多少,灵活与数据库中字段绑定. 2.实现对DB的增删改查,而且操作后listview自己主动刷新. 3.响应用 ...

  9. Android - 标准VideoView播放演示样例

    标准VideoView播放演示样例 本文地址: http://blog.csdn.net/caroline_wendy 在Android SDK中的ApiDemos内, 提供标准播放视频的代码,使用V ...

随机推荐

  1. 设备树学习之(一)GPIO中断【转】

    本文转载自:http://blog.csdn.net/lizuobin2/article/details/54563587 开发板:tiny4412SDK + S702 + 4GB Flash 要移植 ...

  2. nyoj--92--图像有用区域(模拟)

    图像有用区域 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 "ACKing"同学以前做一个图像处理的项目时,遇到了一个问题,他需要摘取出图片中某个黑 ...

  3. Connect the Cities--hdoj

    Connect the Cities Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  4. C++_class_powerpoint_1.1

    Types and Declarations Boolean Type bool type – boolean , logic type bool literal – true, falseint a ...

  5. day63-webservice 11.cxf整合spring

    如果我们有Spring配置文件,怎么把WebService整合到Spring里面,用Ioc容器来管理这个Bean. 做项目的时候一般都是分层:Dao层.Service层.Service层要调Dao层, ...

  6. [Plugin] WEB版一次选择多个文件进行批量上传(swfupload)的解决方案

    URL:http://www.cnblogs.com/chillsrc/archive/2010/02/21/1670594.html 说明:功能完全支持ie和firefox浏览器! 一般的WEB方式 ...

  7. 使用autofac在mvc5下依赖注入

    把遇到的问题汇总一下: 一.安装mvc5版本 命令:pm> Install-Package Autofac 结果安装的Autofac.Integration.Mvc(版本为4.0),所引用的依赖 ...

  8. vue项目中阻止浏览器返回上一页

    vue项目中在某个页面阻止浏览器返回上一页,适用移动端.PC端. 使用场景例如: 首页 与 A页面     来回跳转,那样点击浏览器返回时也会来回跳转,本想当页面在首页的时候就不再返回了,所以这个时候 ...

  9. SSRS 报表 如何加参数

    SSRS 报表 如何加参数 连接上以后出现一个问题 就是给报表加上参数以后报表不断刷新,跟上次那个报表刷新是同样的问题.那么下面我们来解决一下. 1. 这是给报表添加默认参数进入页面后就不断的刷新刷新 ...

  10. vue-cli 安装

    1    node 下载      http://nodejs.cn/download/ 安装 2  npm install vue-cli -g 3  vue init <template-n ...