學(xué)習(xí)Android Material Design(RecyclerView代替ListView)
本文實(shí)例實(shí)現(xiàn)一下 RecyclerView,代碼比較簡(jiǎn)單,適合初學(xué)者,如有錯(cuò)誤,歡迎指出。
復(fù)習(xí) ListView
可以查看這篇文章深入淺出學(xué)習(xí)Android ListView基礎(chǔ),了解關(guān)于ListView 的基礎(chǔ)知識(shí)。
實(shí)現(xiàn)過(guò)程中需要復(fù)寫B(tài)aseAdapter,主要是這4個(gè)方法
- public int getCount() :適配器中數(shù)據(jù)集中 數(shù)據(jù)的個(gè)數(shù),即ListView需要顯示的數(shù)據(jù)個(gè)數(shù)
- public Object getItem(int position) : 獲取數(shù)據(jù)集中與指定索引對(duì)應(yīng)的數(shù)據(jù)項(xiàng)
- public long getItemId(int position) : 獲取指定行對(duì)應(yīng)的ID
- public View getView(int position, View convertView, ViewGroup parent) :獲取每一個(gè)Item的顯示內(nèi)容
一般 ListView 每一項(xiàng)都是相同的布局,若想各個(gè)項(xiàng)實(shí)現(xiàn)不同的布局,可復(fù)寫 getItemViewType和getViewTypeCount實(shí)現(xiàn)
RecyclerView 實(shí)現(xiàn)
1、xml 布局
下面是RecyclerView中每一項(xiàng)的布局 layout下面的item_article_type_1.xml
<?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="關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知"
android:textColor="@color/primary_text" />
<!-- 新聞 發(fā)布時(shí)間 來(lái)源 閱讀次數(shù)-->
<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="科學(xué)研究院" />
<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="講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)..." />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
布局思路就是 CardView里面嵌入了一個(gè)LinearLayout。圖片部分用固定寬度100dp,文字部分利用android:layout_weight=”1”占據(jù)了其他部分。
TextView利用android:gravity=”center”使得標(biāo)題的文字居中。
LinearLayout里面利用android:gravity=”center”使得“2015-01-09 科學(xué)研究院 1129次”居中,
新聞詳情內(nèi)容的TextView利用
android:maxLines="2" android:ellipsize="end"
將文章內(nèi)容限定為2行,超出部分用省略號(hào)顯示。
使用fresco這兒有個(gè)坑需要注意,請(qǐng)移步這篇文章
Android 之 Fresco 顯示圓形圖片 之坑
預(yù)覽效果

新聞列表的 xml 文件,layout 文件夾下面的fragment_article.xml
<?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 實(shí)現(xiàn)
主要步驟是:
根據(jù)上面的 item_article_type_1.xml實(shí)現(xiàn)一個(gè) class ImageItemArticleViewHolder extends RecyclerView.ViewHolder
繼承RecyclerView.Adapter ,class ItemArticleListAdapter extends RecyclerView.Adapter <...>
重寫三個(gè)方法
- public int getItemCount()
- public TestAdapter.ImageItemArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
- public void onBindViewHolder(ImageItemArticleViewHolder holder, int position)
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());
//注意這個(gè)閱讀次數(shù)是 int 類型,需要轉(zhuǎn)化為 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、新聞實(shí)體類 javabean
有新聞的 index,圖片 url,標(biāo)題,發(fā)布時(shí)間,來(lái)源,閱讀次數(shù),新聞內(nèi)容預(yù)覽
/**
* 新聞?lì)?,這是在 RecycleView 使用的新聞 javabean
* 還有一個(gè)新聞詳情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
思路就是開啟一個(gè)異步線程,讀取多條新聞,加入List itemArticleList,由這個(gè)itemArticleList構(gòu)造ItemArticleAdapter,最后利用setAdapter()方法給RecyclerView加上適配器。
public class ArticleFragment extends Fragment {
private static final String STORE_PARAM = "param";
@InjectView(R.id.rcv_article)
RecyclerView rcvArticle;
private String mParam;
//新聞列表數(shù)據(jù)
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", "關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知", "2015-01-09", "科學(xué)研究院", 1129,
"講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)...");
ItemArticle storeInfo2 =
new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知", "2015-01-09", "科學(xué)研究院", 1129,
"講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)...");
ItemArticle storeInfo3 =
new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知", "2015-01-09", "科學(xué)研究院", 1129,
"講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)...");
ItemArticle storeInfo4 =
new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知", "2015-01-09", "科學(xué)研究院", 1129,
"講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)...");
ItemArticle storeInfo5 =
new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知", "2015-01-09", "科學(xué)研究院", 1129,
"講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)...");
ItemArticle storeInfo6 =
new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "關(guān)于舉辦《經(jīng)典音樂(lè)作品欣賞與人文審美》講座的通知", "2015-01-09", "科學(xué)研究院", 1129,
"講座主要內(nèi)容:以中、西方音樂(lè)歷史中經(jīng)典音樂(lè)作品為基礎(chǔ),通過(guò)作曲家及作品創(chuàng)作背景、相關(guān)音樂(lè)文化史知識(shí)及音樂(lè)欣賞常識(shí)...");
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);
}
}
}
效果圖
利用修改布局,線性顯示或者宮格顯示。(以前宮格顯示很麻煩,現(xiàn)在一條命令就好了,google 搞得這么簡(jiǎn)單,我們Android 工程師要失業(yè)的好伐??。。?/p>
rcvArticle.setLayoutManager(new LinearLayoutManager(mAct));//這里用線性顯示 類似于listview // rcvArticle.setLayoutManager(new GridLayoutManager(mAct, 2));//這里用線性宮格顯示 類似于grid view // rcvArticle.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));//這里用線性宮格顯示 類似于瀑布流


知識(shí)點(diǎn)
TextView需要有setText(int resid) 方法,但是這兒 int 表示 resourceId,如果我想把閱讀次數(shù)(int 1123)賦給這個(gè) TextView,不能使用這個(gè)方法。
需要把 int 轉(zhuǎn)化為 String
int 轉(zhuǎn) String 有三種方法 int i =8; String s =Integer.toString(i); String g =String.valueOf(i); String h =i+""; holder.rcvArticleReadtimes.setText(String.valueOf(article.getReadTimes()));
總結(jié) Todo List
- Picasso 圖片緩存庫(kù)的學(xué)習(xí)
- 實(shí)現(xiàn) RecyclerView 每個(gè)項(xiàng)各自的布局
遇到的坑
rcvArticle.setLayoutManager()需要在onActivityCreated()方法里調(diào)用,如果在onCreateView()調(diào)用會(huì)拋出空指針異常。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one_latest, container, false);
mAct = getActivity();
//錯(cuò)誤,需要在onActivityCreated里面調(diào)用
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)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
Android ViewPager制作新手導(dǎo)航頁(yè)(動(dòng)態(tài)加載)
這篇文章主要為大家詳細(xì)介紹了Android ViewPager制作新手導(dǎo)航頁(yè),了解什么是動(dòng)態(tài)加載指示器,感興趣的小伙伴們可以參考一下2016-05-05
Flutter 實(shí)現(xiàn)進(jìn)度條效果
在一些上傳頁(yè)面炫酷的進(jìn)度條效果都是怎么實(shí)現(xiàn)的,今天小編通過(guò)本文給大家分享Flutter 一行代碼快速實(shí)現(xiàn)你的進(jìn)度條效果,感興趣的朋友一起看看吧2020-05-05
Android開發(fā)中數(shù)據(jù)庫(kù)升級(jí)且表添加新列的方法
這篇文章主要介紹了Android開發(fā)中數(shù)據(jù)庫(kù)升級(jí)且表添加新列的方法,結(jié)合具體實(shí)例形式分析了Android數(shù)據(jù)庫(kù)升級(jí)開發(fā)過(guò)程中常見(jiàn)問(wèn)題與相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
Android編程實(shí)現(xiàn)根據(jù)經(jīng)緯度查詢地址并對(duì)獲取的json數(shù)據(jù)進(jìn)行解析的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)根據(jù)經(jīng)緯度查詢地址并對(duì)獲取的json數(shù)據(jù)進(jìn)行解析的方法,結(jié)合實(shí)例形式分析了Android的經(jīng)緯度地址解析與json格式數(shù)據(jù)操作相關(guān)技巧,需要的朋友可以參考下2017-02-02
Android TextView Marquee的應(yīng)用實(shí)例詳解
這篇文章主要介紹了Android TextView Marquee的應(yīng)用實(shí)例詳解的相關(guān)資料,這里說(shuō)明使用方法及簡(jiǎn)單實(shí)例和注意實(shí)現(xiàn),需要的朋友可以參考下2017-08-08
android底部菜單欄實(shí)現(xiàn)原理與代碼
底部菜單欄很重要,我看了一下很多應(yīng)用軟件都是用了底部菜單欄做,我這里使用了tabhost做了一種通用的(就是可以像微信那樣顯示未讀消息數(shù)量的,雖然之前也做過(guò)但是layout下的xml寫的太臃腫,這里去掉了很多不必要的層,個(gè)人看起來(lái)還是不錯(cuò)的,所以貼出來(lái)方便以后使用2013-01-01
Android開發(fā)實(shí)現(xiàn)ImageView加載攝像頭拍攝的大圖功能
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)ImageView加載攝像頭拍攝的大圖功能,涉及Android基于ImageView的攝像頭拍攝圖片加載、保存及權(quán)限控制等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
Android 自定義對(duì)話框 showSetPwdDialog
這篇文章主要介紹了Android 自定義對(duì)話框 showSetPwdDialog的相關(guān)資料,需要的朋友可以參考下2016-03-03

