当前位置: 移动技术网 > IT编程>移动开发>Android > Android RecyclerView线性布局详解(1)

Android RecyclerView线性布局详解(1)

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

淮海医药网,刘志军弟弟,金钗谍影电视剧全集

recyclerview是android 5.0新增的控件,在android-support-v7下面。官方文档对recycleview介绍很简洁到位,如下:

a flexible view for providing a limited window into a large data set.
大概意思就是说:在有限大小的窗口里显示大量数据的一个灵活的view。

下面是reccleview继承图:

这里写图片描述

看到这里我们自然想到了与之类似的控件listview,recyclerview和listview都是在有限的屏幕区域里维护少量的view来进行显示大量的数据,其实recyclerview是listview的升级版,功能更加强大,更加灵活,扩展性更强,google建议使用recycleview替代listview。

下面是recycleview结构图:

这里写图片描述

recycleview主要包括以下几个部件:

1. recyclerview.adapter

数据和视图的分离设计是程序解耦和可维护的重要指标,recycleview作为展示大量数据的view肯定是遵循这个设计的,listview也不例外。通过继承recycleview.adapter即可轻松实现自己的adapter,主要重写recycleview.adapter的下面三个方法即可实现:

public myrecycleviewadapter.myviewholder oncreateviewholder(viewgroup parent, int viewtype) 
public void onbindviewholder(myrecycleviewadapter.myviewholder holder, int position)
public int getitemcount() 

上面myrecycleviewadapter是我自己定义的viewholder

2. viewholder

viewholder用来保存列表中item view引用的类,这样做的目的是重用item视图,从而提高性能。
在listview中,viewholder不是listview自带的,是需要自己定义的,当然你也可以不使用viewholder,这样的后果就是listview每次调用getview()方法的时候都会调用findviewbyid()方法,要知道findviewbyid()性能很差,它通过递归的方式去从view树中找特定的子view的,最终往往带来很差的性能体验,所以使用viewholder也成了优化listview最重要的手段。
在recyclerview中,android内置了recyclerview.viewholder,这意味着viewholder使用成了必须。

3. 分割线 recycleview.itemdecoration

listview添加分割线很简单,只需在listview的xml中配置”divider”属性即可,如:

android:dividerheight="2dp"
android:divider="@color/red"

但recycleview添加分割线是比较麻烦的,并且默认是不带分割线的。但实际开发中一般都需要分割线,使用recycleview.itemdecoration为recycleview添加分割线

4. 布局管理器 layoutmanager

recycleview支持多种布局模式:

1、linearlayoutmanager
线性布局管理器,支持水平布局和垂直布局两种
2、gridlayoutmanager
网格布局管理器
3、staggerdgridlayoutmanager
错列的网格布局管理器,可以实现瀑布流列表

recycleview使用时和listview很类似,直接看一个简单的例子,分别展示一个垂直方向和水平方向上的列表,并且都支持使用颜色和图片做分割线,效果图如下:

这里写图片描述

这里写图片描述

1. mainactivity

package com.cjl.recycleviewtest;
...
public class mainactivity extends appcompatactivity {

 private verticalfragment mverticalfragment;
 private horizontalfragment mhorizontalfragment;

 @override
 protected void oncreate(bundle savedinstancestate) {
 super.oncreate(savedinstancestate);
 setcontentview(r.layout.activity_main);
 //垂直
 mverticalfragment = new verticalfragment();
 //水平
 mhorizontalfragment = new horizontalfragment();
 //默认为设置垂直
 getfragmentmanager().begintransaction().replace(r.id.activity_main, mverticalfragment).commit();
 }

 @override
 public boolean oncreateoptionsmenu(menu menu) {
 menuinflater inflater = getmenuinflater();
 inflater.inflate(r.menu.menu_recycleview, menu);
 return super.oncreateoptionsmenu(menu);
 }

 @override
 public boolean onoptionsitemselected(menuitem item) {
 int id = item.getitemid();
 switch (id) {
  //垂直方向
  case r.id.vertical:
  verticalfragment mverticalfragment = new verticalfragment();
  getfragmentmanager().begintransaction().replace(r.id.activity_main, mverticalfragment).commit();
  break;
  //水平方向
  case r.id.horizontal:
 getfragmentmanager().begintransaction().replace(r.id.activity_main, mhorizontalfragment).commit();
  break;
 }
 return super.onoptionsitemselected(item);
 }
}

mainactivity布局文件 r.layout.activity_main

<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
</framelayout>

2. 垂直方向上 verticalfragment

public class verticalfragment extends fragment implements view.onclicklistener{

 private recyclerview mrecycleviewdrawable;
 private recyclerview mrecycleviewcolor;
 private linearlayoutmanager mmanagercolor;
 private linearlayoutmanager mmanagerdrawable;
 private list<string> mdata;
 private button mdrawable;
 private button mcolor;
 private myrecycleviewadapter mrecycleviewadapter;

 @nullable
 @override
 public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) {
 view view = inflater.inflate(r.layout.fragment_vertical_layout, container, false);
 mrecycleviewdrawable = (recyclerview) view.findviewbyid(r.id.recycleview_drawable);
 mrecycleviewcolor = (recyclerview) view.findviewbyid(r.id.recycleview_color);

 mdrawable = (button) view.findviewbyid(r.id.btn_drawable);
 mdrawable.setonclicklistener(this);
 mcolor = (button) view.findviewbyid(r.id.btn_color);
 mcolor.setonclicklistener(this);
 //1. 颜色分割线
 mmanagercolor = new linearlayoutmanager(getactivity());
 mmanagercolor.setorientation(linearlayoutmanager.vertical);
 mrecycleviewcolor.setlayoutmanager(mmanagercolor);
 //设置颜色分割线
 mrecycleviewcolor.additemdecoration(new lineardivider(getactivity(), linearlayoutmanager.vertical, 10, this.getresources().getcolor(r.color.coloraccent)));

 //2. 图片分割线
 mmanagerdrawable = new linearlayoutmanager(getactivity());
 mmanagerdrawable.setorientation(linearlayoutmanager.vertical);
 mrecycleviewdrawable.setlayoutmanager(mmanagerdrawable);
 //设置图片分割线
 drawable drawable = contextcompat.getdrawable(getactivity(), r.mipmap.divider);
 mrecycleviewdrawable.additemdecoration(new lineardivider(getactivity(), linearlayoutmanager.vertical, 20, drawable));

 mdata = new arraylist<string>();
 initdata(mdata);
 //自定义adapter
 mrecycleviewadapter = new myrecycleviewadapter(getactivity(), r.layout.item_vertical_recycleview, mdata);
 //设置adapter
 mrecycleviewcolor.setadapter(mrecycleviewadapter);
 mrecycleviewdrawable.setadapter(mrecycleviewadapter);
 return view;
 }

 private void initdata(list<string> datalist) {
 for (int i = 0; i < 30; i++) {
  datalist.add("item" + i);
 }
 }

 @override
 public void onclick(view view) {
 int id = view.getid();
 switch (id){
  case r.id.btn_drawable:
  mrecycleviewcolor.setvisibility(view.invisible);
  mrecycleviewdrawable.setvisibility(view.visible);
  break;

  case r.id.btn_color:
  mrecycleviewcolor.setvisibility(view.visible);
  mrecycleviewdrawable.setvisibility(view.invisible);
  break;
 }
 }
}

verticalfragment 的布局文件 r.layout.fragment_vertical_layout

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

 <android.support.v7.widget.recyclerview
 android:id="@+id/recycleview_drawable"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_marginbottom="60dp"/>

 <android.support.v7.widget.recyclerview
 android:id="@+id/recycleview_color"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_marginbottom="60dp"
 android:visibility="invisible"/>

 <linearlayout
 android:id="@+id/lilayout"
 android:orientation="horizontal"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:weightsum="2"
 android:layout_alignparentbottom="true">

 <button
  android:id="@+id/btn_drawable"
  android:layout_width="wrap_content"
  android:layout_height="50dp"
  android:text="图片分割线"
  android:gravity="center"
  android:layout_weight="1"
  android:background="@color/colorprimary"/>

 <button
  android:id="@+id/btn_color"
  android:layout_width="wrap_content"
  android:layout_height="50dp"
  android:text="颜色分割线"
  android:gravity="center"
  android:layout_weight="1"
  android:background="@color/mytv"/>
 </linearlayout>
</relativelayout>

3. 直接继承recyclerview.adapter

public class myrecycleviewadapter extends recyclerview.adapter<myrecycleviewadapter.myviewholder> {

 private layoutinflater mlayoutinflater;
 private list<string> mdatalist;
 private int mitemlayout;

 public myrecycleviewadapter(context context, int itemlayout, list<string> datalist) {
 mlayoutinflater = layoutinflater.from(context);
 mitemlayout = itemlayout;
 mdatalist = datalist;
 }

 @override
 public myrecycleviewadapter.myviewholder oncreateviewholder(viewgroup parent, int viewtype) {
 return new myviewholder(mlayoutinflater.inflate(mitemlayout, parent, false));
 }

 @override
 public void onbindviewholder(myrecycleviewadapter.myviewholder holder, int position) {
 holder.mtextview.settext(mdatalist.get(position));
 }

 @override
 public int getitemcount() {
 return mdatalist.size();
 }

 class myviewholder extends recyclerview.viewholder {

 private textview mtextview;
 public myviewholder(view itemview) {
  super(itemview);
  mtextview = (textview) itemview.findviewbyid(r.id.tv);
 }
 }
}

item布局文件 item_vertical_recycleview.xml

<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content">

 <textview
 android:id="@+id/tv"
 android:gravity="center"
 android:layout_width="match_parent"
 android:layout_height="60dp"/>

</framelayout>

4. 分割线 recyclerview.itemdecoration

public class lineardivider extends recyclerview.itemdecoration {

 private drawable mdividerdarwable;
 private int morientation;
 private int mdividerhight = 1;
 private paint mcolorpaint;

 public final int[] atrrs = new int[]{
  android.r.attr.listdivider
 };

 /*
 orientation 方向
 */
 public lineardivider(context context, int orientation) {
 final typedarray ta = context.obtainstyledattributes(atrrs);
 this.mdividerdarwable = ta.getdrawable(0);
 ta.recycle();
 setorientation(orientation);
 }

 /*
 int orientation 方向
 int dividerhight 分割线的线宽
 drawable dividerdrawable 充当分割线的图片
 */
 public lineardivider(context context, int orientation, int dividerhight, drawable dividerdrawable) {
 this(context, orientation);
 mdividerhight = dividerhight;
 mdividerdarwable = dividerdrawable;
 }

 /*
 int orientation 方向
 int dividerhight 分割线的线宽
 int dividercolor 分割线的颜色
 */
 public lineardivider(context context, int orientation, int dividerhight, int dividercolor) {
 this(context, orientation);
 mdividerhight = dividerhight;
 mcolorpaint = new paint();
 mcolorpaint.setcolor(dividercolor);
 }

 public void setorientation(int orientation) {
 if (orientation != linearlayoutmanager.horizontal && orientation != linearlayoutmanager.vertical) {
  throw new illegalargumentexception("方向参数错误!");
 }
 morientation = orientation;
 }

 @override
 public void ondraw(canvas c, recyclerview parent, recyclerview.state state) {
 super.ondraw(c, parent, state);
 if (morientation == linearlayoutmanager.horizontal) {
  drawhorizontaldivider(c, parent);
 } else {
  drawvirticaldivider(c, parent);
 }
 }

 //画垂直分割线
 public void drawvirticaldivider(canvas c, recyclerview parent) {
 int left = parent.getpaddingleft();
 int right = parent.getwidth() - parent.getpaddingright();
 final int childcount = parent.getchildcount();
 for (int i = 0; i < childcount; i++) {
  final view child = parent.getchildat(i);
  final recyclerview.layoutparams params = (recyclerview.layoutparams) child.getlayoutparams();
  final int top = child.getbottom() + params.bottommargin;
  final int bottom = top + mdividerhight;
  if (mdividerdarwable != null) {
  mdividerdarwable.setbounds(left, top, right, bottom);
  mdividerdarwable.draw(c);
  }
  if (mcolorpaint != null) {
  c.drawrect(left, top, right, bottom, mcolorpaint);
  }
 }
 }

 //画水平分割线
 public void drawhorizontaldivider(canvas c, recyclerview parent) {
 int top = parent.getpaddingtop();
 int bottom = parent.getheight() - parent.getpaddingbottom();
 final int childcount = parent.getchildcount();
 for (int i = 0; i < childcount; i++) {
  final view child = parent.getchildat(i);
  recyclerview.layoutparams params = (recyclerview.layoutparams) child.getlayoutparams();
  final int left = child.getright() + params.rightmargin;
  final int right = left + mdividerhight;
  if (mdividerdarwable != null) {
  mdividerdarwable.setbounds(left, top, right, bottom);
  mdividerdarwable.draw(c);
  }
  if (mcolorpaint != null) {
  c.drawrect(left, top, right, bottom, mcolorpaint);
  }
 }
 }

 @override
 public void getitemoffsets(rect outrect, view view, recyclerview parent, recyclerview.state state) {
 super.getitemoffsets(outrect, view, parent, state);
 if (morientation == linearlayoutmanager.horizontal) {
  outrect.set(0, 0, 0, mdividerhight);
 } else {
  outrect.set(0, 0, mdividerhight, 0);
 }
 }
}


未完待续……

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网