当前位置: 移动技术网 > 移动技术>移动开发>Android > 浅谈RecyclerView(完美替代ListView,GridView)

浅谈RecyclerView(完美替代ListView,GridView)

2019年07月24日  | 移动技术网移动技术  | 我要评论

android recyclerview 是android5.0推出来的,导入support-v7包即可使用。

个人体验来说,recyclerview绝对是一款功能强大的控件。

首先总结下recyclerview的特点:

1.支持不同方向,不同排版模式,实现多种展现数据的形式,涵盖了listview,gridview,瀑布流等数据表现的形式

2.内部实现了回收机制,无需我们考虑view的复用情况

3.取消了onitemclick等点击事件,需要自己手动去写

那么让我们通过一些demo来了解recyclerview的基本使用

 android studio

build.gradle文件中 dependencies中添加

compile 'com.android.support:recyclerview-v7:22.+'

首先,要导入support-v7 包

import android.support.v7.widget.recyclerview;

recyclerview和listview的使用一样,都需要有对应的adapter,列表项布局,数据源

1.先写主activity布局

可以看到recyclerview的标签

<android.support.v7.widget.recyclerview>

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context="com.xqx.superapp.app.android5activity">
 <button
  android:text="添加一个数据"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:onclick="btnadditem"
  />
 <button
  android:text="删除第一个"
  android:onclick="btnremoveitem"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"/>
 <android.support.v7.widget.recyclerview
 android:id="@+id/recycle_view"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 >
 </android.support.v7.widget.recyclerview>
</linearlayout>

菜单项布局,标准的上面图片,下面文字

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:gravity="center"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
 <imageview
  android:id="@+id/item_icon"
  android:src="@mipmap/machao_moqi"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"/>
 <textview
  android:id="@+id/item_title"
  android:text="名称"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  />
</linearlayout>

2.接下来就看activity代码了

首先看成员变量,与listview,gridview一样 标准三样, 控件,数据源,适配器

private list<string> data;  
private recyclerview recyclerview;
private myrecycleadapter adapter; //自定义适配器,继承recyclerview.adapter

接着我们必须要自定义一个viewholder,这个viewholder 必须要继承 recyclerview.viewholder

注意recyclerview不再提供onitemclick事件监听,所以需要我们自己手工写监听事件的方法

private static class viewholder extends recyclerview.viewholder implements view.onclicklistener {
 public imageview imageview;
 public textview textview;
 public viewholder(view itemview) {
  super(itemview);
  // 通常viewholder的构造,就是用于获取控件视图的
  imageview = (imageview) itemview.findviewbyid(r.id.item_icon);
  textview = (textview) itemview.findviewbyid(r.id.item_title);
  // todo 后续处理点击事件的操作
  itemview.setonclicklistener(this);

 }
 @override
 public void onclick(view v) {
  int position = getadapterposition();
  context context = imageview.getcontext();
  toast.maketext(context,"显示第"+position+"个项",toast.length_short).show();
 }
 }

再让我们看自定义适配器,注意这里的参数是viewholder,这个viewhodler是我们自己的,不要导入v7包下的viewholder,

之后要重写三个方法

private class myrecycleadapter extends recyclerview.adapter<viewholder>{ 
@override
public viewholder oncreateviewholder(viewgroup viewgroup, int i) {
 return null;
}
@override
public void onbindviewholder(viewholder viewholder, int i) {
}
@override
public int getitemcount() {
 return 0;
}
}

在自定义适配器myrecycleadapter中,首先要写一个构造方法,因为有数据源,所有构造方法里必然有list

private list<string> strings;
public myrecycleadapter(list<string> strings) {
 this.strings = strings;
}

然后就要重写三个方法了,

@override
public int getitemcount() {
 int ret = 0;
 if (strings != null) {
 ret = strings.size();
 }
 return ret;
}
 @override
 public viewholder oncreateviewholder(viewgroup viewgroup, int i) {
  viewholder ret = null;
  // 不需要检查是否复用,因为只要进入此方法,必然没有复用
  // 因为recyclerview 通过holder检查复用
  view v = layoutinflater.from(android5activity.this).inflate(r.layout.item_recycler, viewgroup, false);
  ret = new viewholder(v);
  return ret;
 }
@override
 public void onbindviewholder(viewholder viewholder, int i) {
  // 1.这里进行图片的加载
  viewholder.textview.settext(strings.get(i));
  int resid = r.mipmap.ic_launcher;
  int index = i%5;
  switch (index){
  case 0:
   resid = r.mipmap.a11;
   break;
  case 1:
   resid = r.mipmap.a33;
   break;
  case 2:
   resid = r.mipmap.a22;
   break;
  }
  viewholder.imageview.setimageresource(resid);
 }

完成自定义适配器和自定义viewholder的代码 就要进行recyclerview的使用了

首先 要了解  recyclerview.layoutmanager 这个属性

用于进行一个布局的设置,可以设置显示模式,listview或者gridview或者瀑布流

1.listview显示模式

// 1.线性布局
  linearlayoutmanager layoutmanager =
   new linearlayoutmanager(this, // 上下文
     linearlayout.vertical, //垂直布局,
     false);

2.gridview显示模式

// 2.grid布局
 recyclerview.layoutmanager layoutmanager =
  new gridlayoutmanager(this,
     2, // 每行显示item项数目
     gridlayoutmanager.horizontal, //水平排列
     false
     );

3.瀑布流显示模式

// 3.瀑布流
 recyclerview.layoutmanager layoutmanager =
  new staggeredgridlayoutmanager(3, // 每行显示的item项数目
   staggeredgridlayoutmanager.vertical); // 垂直排列

以上三种显示模式任意设置一种 就可以继续下面的代码

recyclerview.setlayoutmanager(layoutmanager);
 // 设置 recyclerview的adapter
 // 注意一定在设置了布局管理器之后调用
 adapter = new myrecycleadapter(data);
 recyclerview.setadapter(adapter);

最后记得加上“添加一个数据”,“删除第一个数据”的按钮响应事件。

首先看一下以往我们对listview,gridview等等的删除某一项的操作

先在数据源中删除该位置的数据,然后刷新整个适配器,那么就可能会造成列表闪屏的问题,还有为了删除添加一个数据项而操作整个数据源的问题

public void btnadditem(view view) {
 data.add(0,"time:"+system.currenttimemillis());
 adapter.notifydatasetchanged();
 }
 public void btnremoveitem(view view) {
 if (!data.isempty()) {
  data.remove(0);
 }
 adapter.notifyitemremoved(0);
 }

    而recyclerview为我们提供了一些新的实用的方法:

public void add(viewmodel item, int position) {
 items.add(position, item); //数据源先添加该数据
 notifyiteminserted(position); //在某个位置刷新即可
}
public void remove(viewmodel item) {
 int position = items.indexof(item);
 items.remove(position); //数据源先删除该数据
 notifyitemremoved(position); //在某个位置删除即可
}

完整代码:

package com.xqx.superapp.app;
import android.app.activity;
import android.content.context;
import android.support.v7.app.actionbaractivity;
import android.os.bundle;
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 android.util.log;
import android.view.*;
import android.widget.*;
import java.util.linkedlist;
import java.util.list;
public class android5activity extends activity {
 private list<string> data;
 private recyclerview recyclerview;
 private myrecycleadapter adapter;
 @override
 protected void oncreate(bundle savedinstancestate) {
 super.oncreate(savedinstancestate);
 setcontentview(r.layout.activity_android5);
 data = new linkedlist<string>();
 recyclerview = (recyclerview) findviewbyid(r.id.recycle_view);
 // 设置布局管理器
 // 支持 单列线性排列,支持gridview模式,瀑布流模式
 // 1.线性布局
 linearlayoutmanager layoutmanager =
  new linearlayoutmanager(this, // 上下文     linearlayout.vertical, //垂直布局,
     false);
// // 2.grid布局
// recyclerview.layoutmanager layoutmanager =
//  new gridlayoutmanager(this,
//     2,
//     gridlayoutmanager.horizontal,
//     false
//     );
//
//  // 3.瀑布流
// recyclerview.layoutmanager layoutmanager =
//  new staggeredgridlayoutmanager(3,
//   staggeredgridlayoutmanager.vertical);
 recyclerview.setlayoutmanager(layoutmanager);
 // 设置 recyclerview的adapter
 // 注意一定在设置了布局管理器之后调用
 adapter = new myrecycleadapter(data);
 recyclerview.setadapter(adapter);
 }
 public void btnadditem(view view) {
 data.add(0,"time:"+system.currenttimemillis());
 adapter.notifydatasetchanged();
 }
 public void btnremoveitem(view view) {
 if (!data.isempty()) {
  data.remove(0);
 }
 adapter.notifyitemremoved(0);
 }
 /**
 * 继承recyclerview.adapter,用于显示数据
 * 需要定义并且使用 viewholder ,必须要使用
 */
 private class myrecycleadapter extends recyclerview.adapter<viewholder>{
 private list<string> strings;
 public myrecycleadapter(list<string> strings) {
  this.strings = strings;
 }
 @override
 public int getitemcount() {
  int ret = 0;
  if (strings != null) {
  ret = strings.size();
  }
  return ret;
 }
 @override
 public viewholder oncreateviewholder(viewgroup viewgroup, int i) {
  viewholder ret = null;
  // 不需要检查是否复用,因为只要进入此方法,必然没有复用
  // 因为recyclerview 通过holder检查复用
  view v = layoutinflater.from(android5activity.this).inflate(r.layout.item_recycler, viewgroup, false);
  ret = new viewholder(v);
  return ret;
 }
 @override
 public void onbindviewholder(viewholder viewholder, int i) {
  viewholder.textview.settext(strings.get(i));
  int resid = r.mipmap.ic_launcher;
  int index = i%5;
  switch (index){
  case 0:
   resid = r.mipmap.a11;
   break;
  case 1:
   resid = r.mipmap.a33;
   break;
  case 2:
   resid = r.mipmap.a22;
   break;
  }
  viewholder.imageview.setimageresource(resid);
 }
 }
 /**
 * 创建自己的viewholder ,必须要继承recyclerview.viewholder
 */
 private static class viewholder extends recyclerview.viewholder implements view.onclicklistener {
 public imageview imageview;
 public textview textview;
 public viewholder(view itemview) {
  super(itemview);
  // 通常viewholder的构造,就是用于获取控件视图的
  imageview = (imageview) itemview.findviewbyid(r.id.item_icon);
  textview = (textview) itemview.findviewbyid(r.id.item_title);
  // todo 后续处理点击事件的操作
  itemview.setonclicklistener(this);
 }
 @override
 public void onclick(view v) {
  int position = getadapterposition();
  context context = imageview.getcontext();
  toast.maketext(context,"显示第"+position+"个项",toast.length_short).show();
 }
 }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持移动技术网!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网