本文實例實現一下 recyclerview,代碼比較簡單,適合初學者,如有錯誤,歡迎指出。
復習 listview
可以查看這篇文章深入淺出學習android listview基礎,了解關于listview 的基礎知識。
實現過程中需要復寫baseadapter,主要是這4個方法
- public int getcount() :適配器中數據集中 數據的個數,即listview需要顯示的數據個數
- public object getitem(int position) : 獲取數據集中與指定索引對應的數據項
- public long getitemid(int position) : 獲取指定行對應的id
- public view getview(int position, view convertview, viewgroup parent) :獲取每一個item的顯示內容
一般 listview 每一項都是相同的布局,若想各個項實現不同的布局,可復寫 getitemviewtype和getviewtypecount實現
recyclerview 實現
1、xml 布局
下面是recyclerview中每一項的布局 layout下面的item_article_type_1.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
<?xml version= "1.0" encoding= "utf-8" ?> <android.support.v7.widget.cardview xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:card_view= "http://schemas.android.com/apk/res-auto" xmlns:app= "http://schemas.android.com/apk/res-auto" xmlns:fresco= "http://schemas.android.com/apk/res-auto" android:id= "@+id/cv_item" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:foreground= "?android:attr/selectableitembackground" app:cardcornerradius= "5dp" app:cardelevation= "5dp" app:contentpadding= "2dp" > <linearlayout android:layout_width= "match_parent" android:layout_height= "wrap_content" > <com.facebook.drawee.view.simpledraweeview android:id= "@+id/rcv_article_photo" android:layout_width= "100dp" android:layout_height= "100dp" android:layout_centervertical= "true" fresco:actualimagescaletype= "centerinside" fresco:roundascircle= "true" fresco:roundingbordercolor= "@color/lightslategray" fresco:roundingborderwidth= "1dp" /> <linearlayout android:layout_width= "0dp" android:layout_height= "match_parent" android:layout_weight= "1" android:orientation= "vertical" > <textview android:id= "@+id/rcv_article_title" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_marginleft= "10dp" android:layout_margintop= "2dp" android:gravity= "center" android:text= "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" android:textcolor= "@color/primary_text" /> <!-- 新聞 發布時間 來源 閱讀次數--> <linearlayout android:layout_width= "match_parent" android:layout_height= "wrap_content" android:layout_margintop= "5dp" android:gravity= "center" android:orientation= "horizontal" > <textview android:id= "@+id/rcv_article_date" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_marginleft= "10dp" android:layout_marginright= "2dp" android:text= "2015-01-09" /> <textview android:id= "@+id/rcv_article_source" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_marginleft= "2dp" android:layout_marginright= "2dp" android:text= "科學研究院" /> <textview android:id= "@+id/rcv_article_readtimes" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_marginleft= "2dp" android:layout_marginright= "2dp" android:text= "1129次" /> </linearlayout> <textview android:id= "@+id/rcv_article_preview" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_marginleft= "10dp" android:layout_margintop= "5dp" android:ellipsize= "end" android:maxlines= "2" android:text= "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." /> </linearlayout> </linearlayout> </android.support.v7.widget.cardview> |
布局思路就是 cardview里面嵌入了一個linearlayout。圖片部分用固定寬度100dp,文字部分利用android:layout_weight=”1”占據了其他部分。
textview利用android:gravity=”center”使得標題的文字居中。
linearlayout里面利用android:gravity=”center”使得“2015-01-09 科學研究院 1129次”居中,
新聞詳情內容的textview利用
1
2
|
android:maxlines= "2" android:ellipsize= "end" |
將文章內容限定為2行,超出部分用省略號顯示。
使用fresco這兒有個坑需要注意,請移步這篇文章
android 之 fresco 顯示圓形圖片 之坑
預覽效果
新聞列表的 xml 文件,layout 文件夾下面的fragment_article.xml
1
2
3
4
5
6
7
8
9
10
11
12
|
<?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:orientation= "vertical" > <android.support.v7.widget.recyclerview android:id= "@+id/rcv_article" android:layout_width= "match_parent" android:layout_height= "0dp" android:layout_weight= "1" /> </linearlayout> |
2、adapter 實現
主要步驟是:
根據上面的 item_article_type_1.xml實現一個 class imageitemarticleviewholder extends recyclerview.viewholder
繼承recyclerview.adapter ,class itemarticlelistadapter extends recyclerview.adapter <...>
重寫三個方法
- public int getitemcount()
- public testadapter.imageitemarticleviewholder oncreateviewholder(viewgroup parent, int viewtype)
- public void onbindviewholder(imageitemarticleviewholder holder, int position)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
public class itemarticleadapter extends recyclerview.adapter<itemarticleadapter.imageitemarticleviewholder> { //新聞列表 private list<itemarticle> articlelist; //context private context context; private layoutinflater mlayoutinflater; public itemarticleadapter(context context,list<itemarticle> articlelist) { this .context = context; this .articlelist = articlelist; mlayoutinflater = layoutinflater.from(context); } @override public itemarticleadapter.imageitemarticleviewholder oncreateviewholder(viewgroup parent, int viewtype) { view view = mlayoutinflater.inflate( r.layout.item_article_type_1, parent, false ); return new imageitemarticleviewholder(view); } @override public void onbindviewholder(imageitemarticleviewholder holder, int position) { itemarticle article = articlelist.get(position); holder.rcvarticlephoto.setimageuri(uri.parse(article.getimageurl())); holder.rcvarticletitle.settext(article.gettitle()); holder.rcvarticledate.settext(article.getpublishdate()); holder.rcvarticlesource.settext(article.getsource()); //注意這個閱讀次數是 int 類型,需要轉化為 string 類型 holder.rcvarticlereadtimes.settext(article.getreadtimes()+ "次" ); holder.rcvarticlepreview.settext(article.getpreview()); } @override public int getitemcount() { return articlelist.size(); } class imageitemarticleviewholder extends recyclerview.viewholder { @injectview (r.id.rcv_article_photo) simpledraweeview rcvarticlephoto; @injectview (r.id.rcv_article_title) textview rcvarticletitle; @injectview (r.id.rcv_article_date) textview rcvarticledate; @injectview (r.id.rcv_article_source) textview rcvarticlesource; @injectview (r.id.rcv_article_readtimes) textview rcvarticlereadtimes; @injectview (r.id.rcv_article_preview) textview rcvarticlepreview; public imageitemarticleviewholder(view itemview) { super (itemview); butterknife.inject( this , itemview); } } } |
3、新聞實體類 javabean
有新聞的 index,圖片 url,標題,發布時間,來源,閱讀次數,新聞內容預覽
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
/** * 新聞類,這是在 recycleview 使用的新聞 javabean * 還有一個新聞詳情javabean */ public class itemarticle { private int index; private string imageurl; private string title; private string publishdate; private string source; private int readtimes; private string preview; public itemarticle( int index, string imageurl, string title, string publishdate, string source, int readtimes, string preview) { this .index = index; this .imageurl = imageurl; this .title = title; this .publishdate = publishdate; this .source = source; this .readtimes = readtimes; this .preview = preview; } public int getindex() { return index; } public void setindex( int index) { this .index = index; } public string getimageurl() { return imageurl; } public void setimageurl(string imageurl) { this .imageurl = imageurl; } public string gettitle() { return title; } public void settitle(string title) { this .title = title; } public string getpublishdate() { return publishdate; } public void setpublishdate(string publishdate) { this .publishdate = publishdate; } public string getsource() { return source; } public void setsource(string source) { this .source = source; } public int getreadtimes() { return readtimes; } public void setreadtimes( int readtimes) { this .readtimes = readtimes; } public string getpreview() { return preview; } public void setpreview(string preview) { this .preview = preview; } } |
4、fragment 里面使用 recyclerview
思路就是開啟一個異步線程,讀取多條新聞,加入list itemarticlelist,由這個itemarticlelist構造itemarticleadapter,最后利用setadapter()方法給recyclerview加上適配器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
public class articlefragment extends fragment { private static final string store_param = "param" ; @injectview (r.id.rcv_article) recyclerview rcvarticle; private string mparam; //新聞列表數據 private list<itemarticle> itemarticlelist = new arraylist<itemarticle>(); //獲取 fragment 依賴的 activity,方便使用 context private activity mact; public static fragment newinstance(string param) { articlefragment fragment = new articlefragment(); bundle args = new bundle(); args.putstring(store_param, param); fragment.setarguments(args); return fragment; } @override public void oncreate(bundle savedinstancestate) { super .oncreate(savedinstancestate); if (getarguments() != null ) { mparam = getarguments().getstring(store_param); } } @nullable @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view = inflater.inflate(r.layout.fragment_article, null ); log.i(store_param, "in storefragment" ); mact = getactivity(); butterknife.inject( this , view); return view; } @override public void onactivitycreated( @nullable bundle savedinstancestate) { super .onactivitycreated(savedinstancestate); rcvarticle.setlayoutmanager( new linearlayoutmanager(mact)); //這里用線性顯示 類似于listview // rcvarticle.setlayoutmanager(new gridlayoutmanager(mact, 2));//這里用線性宮格顯示 類似于grid view // rcvarticle.setlayoutmanager(new staggeredgridlayoutmanager(2, orientationhelper.vertical));//這里用線性宮格顯示 類似于瀑布流 new latestarticletask().execute(); } @override public void ondestroyview() { super .ondestroyview(); butterknife.reset( this ); } class latestarticletask extends asynctask<string, void , list<itemarticle>> { @override protected void onpreexecute() { super .onpreexecute(); } @override protected list<itemarticle> doinbackground(string... params) { itemarticle storeinfo1 = new itemarticle( 20123 , "http://i2.sinaimg.cn/ent/j/2012-05-20/u5912p28t3d3634984f328dt20120520152700.jpg" , "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" , "2015-01-09" , "科學研究院" , 1129 , "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." ); itemarticle storeinfo2 = new itemarticle( 20123 , "http://i2.sinaimg.cn/ent/j/2012-05-20/u5912p28t3d3634984f328dt20120520152700.jpg" , "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" , "2015-01-09" , "科學研究院" , 1129 , "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." ); itemarticle storeinfo3 = new itemarticle( 20123 , "http://i2.sinaimg.cn/ent/j/2012-05-20/u5912p28t3d3634984f328dt20120520152700.jpg" , "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" , "2015-01-09" , "科學研究院" , 1129 , "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." ); itemarticle storeinfo4 = new itemarticle( 20123 , "http://i2.sinaimg.cn/ent/j/2012-05-20/u5912p28t3d3634984f328dt20120520152700.jpg" , "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" , "2015-01-09" , "科學研究院" , 1129 , "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." ); itemarticle storeinfo5 = new itemarticle( 20123 , "http://i2.sinaimg.cn/ent/j/2012-05-20/u5912p28t3d3634984f328dt20120520152700.jpg" , "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" , "2015-01-09" , "科學研究院" , 1129 , "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." ); itemarticle storeinfo6 = new itemarticle( 20123 , "http://i2.sinaimg.cn/ent/j/2012-05-20/u5912p28t3d3634984f328dt20120520152700.jpg" , "關于舉辦《經典音樂作品欣賞與人文審美》講座的通知" , "2015-01-09" , "科學研究院" , 1129 , "講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." ); itemarticlelist.add(storeinfo1); itemarticlelist.add(storeinfo2); itemarticlelist.add(storeinfo3); itemarticlelist.add(storeinfo4); itemarticlelist.add(storeinfo5); itemarticlelist.add(storeinfo6); return itemarticlelist; } @override protected void onpostexecute(list<itemarticle> data) { super .onpostexecute(data); itemarticleadapter adapter = new itemarticleadapter(mact, data); rcvarticle.setadapter(adapter); } } } |
效果圖
利用修改布局,線性顯示或者宮格顯示。(以前宮格顯示很麻煩,現在一條命令就好了,google 搞得這么簡單,我們android 工程師要失業的好伐?!!)
1
2
3
|
rcvarticle.setlayoutmanager( new linearlayoutmanager(mact)); //這里用線性顯示 類似于listview // rcvarticle.setlayoutmanager(new gridlayoutmanager(mact, 2));//這里用線性宮格顯示 類似于grid view // rcvarticle.setlayoutmanager(new staggeredgridlayoutmanager(2, orientationhelper.vertical));//這里用線性宮格顯示 類似于瀑布流 |
知識點
textview需要有settext(int resid) 方法,但是這兒 int 表示 resourceid,如果我想把閱讀次數(int 1123)賦給這個 textview,不能使用這個方法。
需要把 int 轉化為 string
1
2
3
4
5
6
|
int 轉 string 有三種方法 int i = 8 ; string s =integer.tostring(i); string g =string.valueof(i); string h =i+ "" ; holder.rcvarticlereadtimes.settext(string.valueof(article.getreadtimes())); |
總結 todo list
- picasso 圖片緩存庫的學習
- 實現 recyclerview 每個項各自的布局
遇到的坑
rcvarticle.setlayoutmanager()需要在onactivitycreated()方法里調用,如果在oncreateview()調用會拋出空指針異常。
1
2
3
4
5
6
7
8
9
|
public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view = inflater.inflate(r.layout.fragment_one_latest, container, false ); mact = getactivity(); //錯誤,需要在onactivitycreated里面調用 rcvarticle.setlayoutmanager( new linearlayoutmanager(mact)); //這里用線性顯示 類似于listview butterknife.inject( this , view); return view; } |
java.lang.nullpointerexception
at com.example.administrator.seenews.ui.fragment.common.articlefragment.oncreateview(articlefragment.java:111)
以上就是本文的全部內容,希望對大家的學習有所幫助。