当前位置: 移动技术网 > IT编程>移动开发>Android > Android RecycleView多种布局实现(工厂模式)

Android RecycleView多种布局实现(工厂模式)

2018年10月23日  | 移动技术网IT编程  | 我要评论

望洞庭 古诗,精细滤油车,妖孽宝贝痞子妈

recycleview是个很常用的控件,很多app中都可以看到它的身影,同时它也是个很难用的控件,主要就难在多种布局的实现。

在《第一行代码—android》这本书里边有个recycleview实现的聊天界面布局,左右两种布局写在了同一个文件中,如果是发送来的消息,就隐藏右侧布局,反之隐藏左侧布局,这种方式对于比较简单的、只有两种item的界面是可行的,假如我们的item有多种布局,那么这种方式就显得很笨重。对于多种布局,我们可以使用工厂模式来实现。

 

1.首先看看效果(gif一直上传失败,只好传jpg了):

这里的layoutmanager使用gridlayoutmanager,设置为6列,然后在adapter类中根据不同的类型来设置所占列数,具体见adapter类的setspancount方法。

 

2.然后是类图:

 

3.adapter类:

适配器的代码很短,设置数据和绑定view的代码都写在了itemholder的子类里面;

list<item>储存三种类型的item数据,如果需要增加新的类型,只要实现item接口就可以了;

在onbindviewholder方法中调用itemholder的setdata()方法来设置数据;

 1 public class multilistadapter extends recyclerview.adapter<itemholder> {
 2 
 3     private list<item> mdatalist;
 4 
 5     public multilistadapter(list<item> datalist) {
 6         mdatalist = datalist;
 7     }
 8 
 9     @nonnull
10     @override
11     public itemholder oncreateviewholder(@nonnull viewgroup viewgroup, int type) {
12         return itemholderfactory.getitemholder(viewgroup, type);
13     }
14 
15     @override
16     public void onbindviewholder(@nonnull itemholder viewholder, int i) {
17         //设置 holder 数据
18         viewholder.setdata(mdatalist.get(i));
19     }
20 
21     @override
22     public int getitemviewtype(int position) {
23         return mdatalist.get(position).gettype();
24     }
25 
26     @override
27     public int getitemcount() {
28         return mdatalist.size();
29     }
30 
31     public void setspancount(gridlayoutmanager layoutmanager) {
32         layoutmanager.setspansizelookup(new gridlayoutmanager.spansizelookup() {
33             @override
34             public int getspansize(int i) {
35                 int type = getitemviewtype(i);
36                 switch (type) {
37                     default:
38                     case itemholderfactory.item_large:
39                         return 3;
40                     case itemholderfactory.item_small:
41                         return 2;
42                     case itemholderfactory.item_title_bar:
43                         return 6;
44                 }
45             }
46         });
47     }
48 }

4.itemholder抽象类:

setdata方法用来设置item布局的数据

1 public abstract class itemholder extends recyclerview.viewholder {
2     public itemholder(view item) {
3         super(item);
4     }
5 
6     public abstract void setdata(item itemdata);
7 }

5.largeitemholder类:

另外两个类似

 1 public class largeitemholder extends itemholder {
 2 
 3     private imageview mitemimage;
 4     private textview mtitle;
 5     private textview msubtitle;
 6 
 7     public largeitemholder(view item) {
 8         super(item);
 9         mitemimage = item.findviewbyid(r.id.item_image);
10         mtitle = item.findviewbyid(r.id.item_title);
11         msubtitle = item.findviewbyid(r.id.item_sub_title);
12     }
13 
14     @override
15     public void setdata(item itemdata) {
16         itemlarge item = (itemlarge) itemdata;
17         mitemimage.setimagebitmap(item.getimage());
18         mtitle.settext(item.gettitle());
19         msubtitle.settext(item.getsubtitle());
20     }
21 }

6.item接口:

1 public interface item {
2     int gettype();
3 }

7.itemlarge类(一个图片、一个标题和一个副标题):

另外两个类似

 1 public class itemlarge implements item {
 2 
 3     private bitmap mimage;
 4     private string mtitle;
 5     private string msubtitle;
 6 
 7     public itemlarge(bitmap bitmap, string title, string subtitle) {
 8         mimage = bitmap;
 9         mtitle = title;
10         msubtitle = subtitle;
11     }
12 
13     public bitmap getimage() {
14         return mimage;
15     }
16 
17     public string gettitle() {
18         return mtitle;
19     }
20 
21     public string getsubtitle() {
22         return msubtitle;
23     }
24 
25     @override
26     public int gettype() {
27         return itemholderfactory.item_large;
28     }
29 }

8.工厂类itemholderfactory:

三个常量表示不同的布局类型,通过getitemholder来创建viewholder。

 1 public class itemholderfactory {
 2 
 3     public static final int item_large = 0;
 4     public static final int item_small = 1;
 5     public static final int item_title_bar = 2;
 6 
 7     @intdef({
 8             item_large,
 9             item_small,
10             item_title_bar
11     })
12     @interface itemtype {}
13 
14     static itemholder getitemholder(viewgroup parent, @itemtype int type) {
15         switch (type) {
16             default:
17             case item_large:
18                 return new largeitemholder(layoutinflater
19                         .from(parent.getcontext()).inflate(r.layout.item_large, parent, false));
20             case item_small:
21                 return new smallitemholder(layoutinflater
22                         .from(parent.getcontext()).inflate(r.layout.item_small, parent, false));
23             case item_title_bar:
24                 return new titlebaritemholder(layoutinflater
25                         .from(parent.getcontext()).inflate(r.layout.item_title_bar, parent, false));
26         }
27     }
28 }

9.listactivity类:

 1 public class listactivity extends appcompatactivity {
 2 
 3     list<item> itemlist = new arraylist<>();
 4 
 5     @override
 6     protected void oncreate(bundle savedinstancestate) {
 7         super.oncreate(savedinstancestate);
 8         setcontentview(r.layout.activity_list);
 9 
10         initdata();
11 
12         gridlayoutmanager layoutmanager = new gridlayoutmanager(this, 6);
13         multilistadapter adapter = new multilistadapter(itemlist);
14         adapter.setspancount(layoutmanager);
15 
16         recyclerview recyclerview = findviewbyid(r.id.recycle_view);
17         recyclerview.setlayoutmanager(layoutmanager);
18         recyclerview.setadapter(adapter);
19     }
20 
21     private void initdata() {
22         //添加数据
23         itemlist.add(new itemtitlebar("hot new", null));
24         itemlist.add(new itemlarge(
25                 bitmapfactory.decoderesource(getresources(), r.drawable.img_1),
26                 "one more light",
27                 "linkin park"));
28         itemlist.add(new itemlarge(
29                 bitmapfactory.decoderesource(getresources(), r.drawable.img_2),
30                 "let go ",
31                 "avril lavigne"));
32         itemlist.add(new itemtitlebar("recommended", null));
33         itemlist.add(new itemsmall(
34                 bitmapfactory.decoderesource(getresources(), r.drawable.img_3),
35                 "bridge to terabithia"));
36         itemlist.add(new itemsmall(
37                 bitmapfactory.decoderesource(getresources(), r.drawable.img_4),
38                 "life is beautiful"));
39         itemlist.add(new itemsmall(
40                 bitmapfactory.decoderesource(getresources(), r.drawable.img_5),
41                 "a violent flame"));
42         itemlist.add(new itemtitlebar("top rated", null));
43         itemlist.add(new itemlarge(
44                 bitmapfactory.decoderesource(getresources(), r.drawable.img_6),
45                 "furious 7: original motion picture soundtrack",
46                 "various artists"));
47         itemlist.add(new itemlarge(
48                 bitmapfactory.decoderesource(getresources(), r.drawable.img_7),
49                 "halo 5: guardians (original soundtrack)",
50                 "kazuma jinnouchi"));
51     }
52 }

10.布局文件(item_large.xml):

layout_width用match_parent是为了item在网格中居中,此处match_parent相当于宽度为item所占的列数。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:orientation="vertical"
 5     android:layout_width="match_parent"
 6     android:layout_height="wrap_content"
 7     android:layout_margin="4dp"
 8     android:background="#ffffff"
 9     android:elevation="2dp">
10 
11     <imageview
12         android:contentdescription="@id/item_title"
13         android:id="@+id/item_image"
14         android:layout_width="match_parent"
15         android:layout_height="170dp"
16         android:scaletype="centercrop"
17         tools:src="@drawable/img_7" />
18 
19     <textview
20         android:id="@+id/item_title"
21         android:layout_width="match_parent"
22         android:layout_height="wrap_content"
23         android:layout_margintop="8dp"
24         android:paddingstart="8dp"
25         android:paddingend="8dp"
26         android:lines="1"
27         android:ellipsize="end"
28         android:textcolor="#000000"
29         android:textsize="18sp"
30         tools:text="item title" />
31 
32     <textview
33         android:id="@+id/item_sub_title"
34         android:layout_width="match_parent"
35         android:layout_height="wrap_content"
36         android:layout_marginbottom="8dp"
37         android:paddingstart="8dp"
38         android:paddingend="8dp"
39         android:lines="1"
40         android:ellipsize="end"
41         android:textsize="14sp"
42         tools:text="sub title" />
43 
44 </linearlayout>

 

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

相关文章:

验证码:
移动技术网