本文实例实现一下 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)
以上就是本文的全部内容,希望对大家的学习有所帮助。