安卓開發筆記——打造屬於本身的博客園APP(四)

  在上篇文章《安卓開發筆記——打造屬於本身的博客園APP(三)》中,咱們對博客文章的詳情頁和評論頁進行了實現,慢慢的一個APP已經出現雛形了,固然這只是完成了"表面效果",要真正作好一個APP並非一件很輕鬆的事情,有不少細節須要咱們一點一滴的去完善。html

  好了,來說下今天要完成的效果,在優化了以前部分代碼的前提下,今天來講下關於博客搜索和博客詳情頁的實現,依舊國際慣例,來看下效果圖:(動態圖片比較大,加載須要點時間)java

  效果比較簡單,不少東西咱們仍是能夠複用以前的代碼,畢竟這種列表長得都差很少,而後大體功能基本完成了,從下篇文章開始能夠引入咱們的數據庫了,開始實現緩存操做。android

 

一、關於搜索頁面的實現:數據庫

  很簡單,分紅兩部分,上面一個EditText,下面一個RecyclerView,當咱們剛進入頁面的時候默認展現博客園給咱們的推薦用戶,當搜索的時候更新列表數據。瀏覽器

  這裏是關於博客園推薦用戶的接口: http://wcf.open.cnblogs.com/blog/bloggers/recommend/{PAGEINDEX}/{PAGESIZE} {PAGEINDEX}表明頁碼,{PAGESIZE}表明每頁展現的條數緩存

這裏是搜索頁面的主佈局文件:app

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical">
 6 
 7 
 8     <!--ToolBar-->
 9     <include layout="@layout/activity_toolbar" />
10 
11     <LinearLayout
12         android:layout_width="match_parent"
13         android:layout_height="wrap_content"
14         android:background="@color/md_green_700"
15         android:paddingBottom="10dp"
16         android:paddingLeft="20dp"
17         android:paddingRight="20dp"
18         android:paddingTop="10dp">
19 
20         <RelativeLayout
21             android:layout_width="match_parent"
22             android:layout_height="40dp"
23             android:background="@drawable/bg_search"
24             android:gravity="center_vertical">
25 
26             <ImageButton
27                 android:id="@+id/ib_search"
28                 android:layout_width="wrap_content"
29                 android:layout_height="wrap_content"
30                 android:layout_alignParentRight="true"
31                 android:background="@drawable/bt_search_selector" />
32 
33             <EditText
34                 android:id="@+id/et_text"
35                 android:layout_width="match_parent"
36                 android:layout_height="wrap_content"
37                 android:layout_toLeftOf="@id/ib_search"
38                 android:background="@null"
39                 android:hint="搜索其餘博客" />
40         </RelativeLayout>
41     </LinearLayout>
42 
43     <FrameLayout
44         android:layout_width="match_parent"
45         android:layout_height="match_parent">
46 
47         <android.support.v7.widget.RecyclerView
48             android:id="@+id/rv_view"
49             android:layout_width="match_parent"
50             android:layout_height="match_parent"
51             android:background="@color/md_grey_200"
52             android:scrollbars="none" />
53 
54         <com.lcw.rabbit.myblog.view.MyProgressBar
55             android:id="@+id/progressbar"
56             android:layout_width="match_parent"
57             android:layout_height="20dp"
58             android:layout_gravity="bottom"
59             android:visibility="gone" />
60     </FrameLayout>
61 </LinearLayout>
activity_search.xml

這裏是下面RecyclerView列表的Item佈局:ide

 1 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:app="http://schemas.android.com/apk/res-auto"
 3     android:layout_width="match_parent"
 4     android:layout_height="wrap_content"
 5     android:layout_margin="8dp"
 6     android:gravity="center"
 7     app:cardCornerRadius="6dp">
 8 
 9     <include layout="@layout/recyclerview_item_authorlist_content" />
10 
11 </android.support.v7.widget.CardView>
recyclerview_item_authorlist.xml

這裏是Item佈局的詳細:工具

  1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2     xmlns:app="http://schemas.android.com/apk/res-auto"
  3     android:layout_width="match_parent"
  4     android:layout_height="wrap_content"
  5     android:background="?android:selectableItemBackground"
  6     android:orientation="horizontal"
  7     android:padding="3dp">
  8     <!--頭像-->
  9     <com.makeramen.roundedimageview.RoundedImageView
 10         android:id="@+id/iv_userhead"
 11         android:layout_width="60dp"
 12         android:layout_height="60dp"
 13         android:layout_gravity="center_vertical"
 14         android:layout_marginRight="5dp"
 15         android:src="@mipmap/avatar_default"
 16         app:riv_border_color="#ffffff"
 17         app:riv_border_width="2dip"
 18         app:riv_corner_radius="30dip"
 19         app:riv_mutate_background="true"
 20         app:riv_oval="true"
 21         app:riv_tile_mode="repeat" />
 22     <!--信息內容-->
 23     <LinearLayout
 24         android:layout_width="0dp"
 25         android:layout_height="wrap_content"
 26         android:layout_marginLeft="3dp"
 27         android:layout_weight="1"
 28         android:orientation="vertical">
 29 
 30         <TextView
 31             android:id="@+id/tv_name"
 32             android:layout_width="match_parent"
 33             android:layout_height="wrap_content"
 34             android:layout_marginTop="2dp"
 35             android:layout_weight="1"
 36             android:ellipsize="end"
 37             android:singleLine="true"
 38             android:text="測試標題"
 39             android:textColor="@color/md_grey_900"
 40             android:textSize="16sp"
 41             android:textStyle="bold" />
 42 
 43         <TextView
 44             android:id="@+id/tv_url"
 45             android:layout_width="match_parent"
 46             android:layout_height="wrap_content"
 47             android:layout_weight="1"
 48             android:maxLines="3"
 49             android:text="瀏覽器類型判斷方法有兩種:根據瀏覽器特性來判斷根據來檢測具體使用哪一種方法要看具體需求的場景場景一:爲了讓用戶有較流暢完整的體驗,在站點提示用戶使用或者,這種場景對瀏覽器類型的判斷並不是特別嚴格,可使用檢測的方法。(由於不少瀏覽器廠商會篡改標識)。場景二...."
 50             android:textSize="14sp" />
 51 
 52         <LinearLayout
 53             android:layout_width="match_parent"
 54             android:layout_height="match_parent"
 55             android:layout_margin="1dp"
 56             android:layout_weight="1"
 57             android:orientation="horizontal">
 58 
 59             <TextView
 60                 android:layout_width="wrap_content"
 61                 android:layout_height="match_parent"
 62                 android:gravity="center_vertical"
 63                 android:text="博文數:"
 64                 android:textColor="@color/md_grey_500"
 65                 android:textSize="12sp" />
 66 
 67             <TextView
 68                 android:id="@+id/tv_sum"
 69                 android:layout_width="wrap_content"
 70                 android:layout_height="match_parent"
 71                 android:layout_marginRight="5dp"
 72                 android:gravity="center_vertical"
 73                 android:textColor="@color/md_grey_500"
 74                 android:textSize="12sp" />
 75 
 76             <TextView
 77                 android:layout_width="wrap_content"
 78                 android:layout_height="match_parent"
 79                 android:gravity="center_vertical"
 80                 android:text="最後更新:"
 81                 android:textColor="@color/md_grey_500"
 82                 android:textSize="12sp" />
 83 
 84             <TextView
 85                 android:id="@+id/tv_time"
 86                 android:layout_width="wrap_content"
 87                 android:layout_height="match_parent"
 88                 android:layout_marginRight="5dp"
 89                 android:textColor="@color/md_grey_500"
 90                 android:textSize="12sp" />
 91 
 92         </LinearLayout>
 93 
 94     </LinearLayout>
 95 
 96     <!--操做按鈕-->
 97     <ImageButton
 98         android:id="@+id/ib_more"
 99         android:layout_width="25dp"
100         android:layout_height="match_parent"
101         android:background="?android:selectableItemBackground"
102         android:gravity="center_horizontal"
103         android:src="@mipmap/triangle" />
104 </LinearLayout>
recyclerview_item_authorlist_content.xml

關於博客園推薦博客的接口數據XML解析,和咱們以前在作博文列表數據的解析都是同樣的,只不過是XML的節點不一樣,這裏貼出解析代碼:佈局

  1 package com.lcw.rabbit.myblog.parser;
  2 
  3 import com.lcw.rabbit.myblog.entity.Author;
  4 
  5 import org.xmlpull.v1.XmlPullParser;
  6 import org.xmlpull.v1.XmlPullParserException;
  7 import org.xmlpull.v1.XmlPullParserFactory;
  8 
  9 import java.io.IOException;
 10 import java.io.InputStream;
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 
 14 /**
 15  * 對博客做者(列表)xml數據的解析
 16  * Created by Lichenwei
 17  * Date: 2015-08-17
 18  * Time: 13:32
 19  */
 20 public class AuthorListXmlParser {
 21 
 22 
 23     /**
 24      * 用於解析博客做者(列表)的xml,返回Avatar的List集合對象
 25      *
 26      * @param inputStream
 27      * @param encode
 28      * @return
 29      * @throws XmlPullParserException
 30      * @throws IOException
 31      */
 32     public static List<Author> getListAuthor(InputStream inputStream, String encode) throws XmlPullParserException, IOException {
 33 
 34         List<Author> mAuthors = null;
 35         Author mAuthor = null;
 36 
 37         //獲取XmlPullParser實例
 38         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
 39         XmlPullParser parser = factory.newPullParser();
 40         parser.setInput(inputStream, encode);
 41         //獲取解析事件
 42         int eventType = parser.getEventType();
 43         //當xml文檔未到尾端時
 44         while (eventType != XmlPullParser.END_DOCUMENT) {
 45             switch (eventType) {
 46                 //解析根標籤的時候,實例化集合
 47                 case XmlPullParser.START_DOCUMENT:
 48                     mAuthors = new ArrayList<Author>();
 49                     mAuthor = new Author();
 50 
 51                     break;
 52                 case XmlPullParser.START_TAG:
 53                     //當解析到entry標籤的時候,實例化Avatar對象
 54                     if ("entry".equals(parser.getName())) {
 55                         mAuthor = new Author();
 56                     }
 57                     if ("id".equals(parser.getName())) {
 58                         parser.next();
 59                         mAuthor.setAuthorUrl(parser.getText());
 60                     } else if ("title".equals(parser.getName())) {
 61                         parser.next();
 62                         if (parser.getText().indexOf("博客園") == -1) {
 63                             mAuthor.setAuthorName(parser.getText());
 64                         }
 65                     } else if ("avatar".equals(parser.getName())) {
 66                         parser.next();
 67                         mAuthor.setAuthorPic(parser.getText());
 68                     } else if ("blogapp".equals(parser.getName())) {
 69                         parser.next();
 70                         mAuthor.setBlogApp(parser.getText());
 71                     } else if ("postcount".equals(parser.getName())) {
 72                         parser.next();
 73                         mAuthor.setBlogCount(parser.getText());
 74                     } else if ("updated".equals(parser.getName())) {
 75                         parser.next();
 76                         //區分日期格式
 77                         if (parser.getText().indexOf("+") != -1) {
 78                             mAuthor.setUpdated(parser.getText());
 79                         }
 80 
 81                     }
 82                     break;
 83                 case XmlPullParser.END_TAG:
 84                     //當解析到entry標籤結束的時候添加入Avatar集合,清空Avatar對象
 85                     if ("entry".equals(parser.getName())) {
 86                         mAuthors.add(mAuthor);
 87                         mAuthor = null;
 88                     }
 89                     break;
 90 
 91             }
 92             //手動跳轉第一次遍歷
 93             eventType = parser.next();
 94         }
 95 
 96 
 97         return mAuthors;
 98 
 99     }
100 
101 }

  這裏是搜索主頁面代碼,當咱們點擊搜索按鈕的時候,獲取輸入框的博客關鍵字,進行搜索,將獲得的數據更新數據源從新展現在RecyclerView。

  關於搜索博客關鍵字的接口:http://wcf.open.cnblogs.com/blog/bloggers/search?t={TERM} {TERM}表明做者名(多關鍵字匹配),搜索到的XML數據信息恰好又和咱們前面的推薦博客內容格式一致,因此咱們能夠複用以前的解析工具類,而後同樣具有上拉刷新和下拉加載功能:

  1 package com.lcw.rabbit.myblog;
  2 
  3 import android.content.Intent;
  4 import android.os.Bundle;
  5 import android.support.v7.app.AppCompatActivity;
  6 import android.support.v7.widget.LinearLayoutManager;
  7 import android.support.v7.widget.RecyclerView;
  8 import android.support.v7.widget.Toolbar;
  9 import android.view.View;
 10 import android.widget.EditText;
 11 import android.widget.ImageButton;
 12 import android.widget.Toast;
 13 
 14 import com.afollestad.materialdialogs.MaterialDialog;
 15 import com.android.volley.Request;
 16 import com.android.volley.Response;
 17 import com.android.volley.VolleyError;
 18 import com.android.volley.toolbox.StringRequest;
 19 import com.lcw.rabbit.myblog.adapter.AuthorListAdapter;
 20 import com.lcw.rabbit.myblog.entity.Author;
 21 import com.lcw.rabbit.myblog.entity.Blog;
 22 import com.lcw.rabbit.myblog.parser.AuthorListXmlParser;
 23 import com.lcw.rabbit.myblog.utils.VolleyRequestQueueManager;
 24 import com.lcw.rabbit.myblog.view.MyProgressBar;
 25 import com.mugen.Mugen;
 26 import com.mugen.MugenCallbacks;
 27 import com.mugen.attachers.BaseAttacher;
 28 
 29 import org.xmlpull.v1.XmlPullParserException;
 30 
 31 import java.io.ByteArrayInputStream;
 32 import java.io.IOException;
 33 import java.util.ArrayList;
 34 import java.util.List;
 35 
 36 /**
 37  * 博客搜索頁
 38  */
 39 public class SearchActivity extends AppCompatActivity {
 40 
 41     //界面控件
 42     private Toolbar mToolbar;
 43     private EditText mEditText;
 44     private ImageButton mImageButton;
 45     private RecyclerView mRecyclerView;
 46     private MaterialDialog materialDialog;
 47     //無限滾動
 48     private BaseAttacher mBaseAttacher;
 49     private MyProgressBar myProgressBar;
 50 
 51     //數據源
 52     private AuthorListAdapter mAuthorListAdapter;
 53     private List<Author> mAuthors;
 54 
 55     //標誌變量
 56     private boolean isLoading = false;
 57     private int currentPage = 1;
 58 
 59 
 60     @Override
 61     protected void onCreate(Bundle savedInstanceState) {
 62         super.onCreate(savedInstanceState);
 63         setContentView(R.layout.activity_search);
 64         initView();
 65         initData();
 66         initAction();
 67     }
 68 
 69     /**
 70      * 設置控件監聽
 71      */
 72     private void initAction() {
 73         //設置無限滾動,上拉加載
 74         mBaseAttacher = Mugen.with(mRecyclerView, new MugenCallbacks() {
 75             @Override
 76             public void onLoadMore() {
 77                 //加載更多
 78                 isLoading = true;
 79                 mBaseAttacher.setLoadMoreEnabled(false);
 80                 myProgressBar.setVisibility(View.VISIBLE);
 81                 getData((currentPage + 1), 10);
 82             }
 83 
 84             @Override
 85             public boolean isLoading() {
 86                 return isLoading;
 87             }
 88 
 89             @Override
 90             public boolean hasLoadedAllItems() {
 91                 return isLoading;
 92             }
 93         }).start();
 94         //離底部一項的時候加載更多
 95         mBaseAttacher.setLoadMoreOffset(1);
 96 
 97         //點擊搜索
 98         mImageButton.setOnClickListener(new View.OnClickListener() {
 99             @Override
100             public void onClick(View v) {
101                 materialDialog = new MaterialDialog.Builder(SearchActivity.this).content("內容加載中..").progress(true, 0).show();
102                 String name = mEditText.getText().toString();
103                 getDataByName(name.trim());
104             }
105         });
106 
107         //設置RecyclerView點擊監聽
108         mAuthorListAdapter.setRecyclerViewListener(new AuthorListAdapter.RecyclerViewListener() {
109             @Override
110             public void setOnclickListener(View view, String value) {
111                 //封裝Bolg對象傳遞
112                 Blog blog = new Blog();
113                 blog.setBlogApp(mAuthors.get(Integer.parseInt(value)).getBlogApp());
114                 blog.setAuthorName(mAuthors.get(Integer.parseInt(value)).getAuthorName());
115                 Intent intent = new Intent();
116                 intent.setClass(SearchActivity.this, AuthorActivity.class);
117                 Bundle bundle = new Bundle();
118                 bundle.putSerializable("blog", blog);
119                 intent.putExtras(bundle);
120                 startActivity(intent);
121             }
122         });
123     }
124 
125     /**
126      * 初始化控件
127      */
128     private void initView() {
129         //ToolBar
130         mToolbar = (Toolbar) findViewById(R.id.activity_toolbar);
131         setSupportActionBar(mToolbar);
132         //須要放在setSupportActionBar後設置
133         mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
134             @Override
135             public void onClick(View v) {
136                 finish();
137             }
138         });
139         getSupportActionBar().setTitle("博客搜索");
140         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
141 
142         //輸入搜索
143         mEditText = (EditText) findViewById(R.id.et_text);
144         mImageButton = (ImageButton) findViewById(R.id.ib_search);
145         //列表
146         mRecyclerView = (RecyclerView) findViewById(R.id.rv_view);
147         mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
148         //當高度肯定,提升效率
149         mRecyclerView.setHasFixedSize(true);
150         //友好提醒
151         myProgressBar = (MyProgressBar) findViewById(R.id.progressbar);
152 
153     }
154 
155     /**
156      * 初始化數據
157      */
158     private void initData() {
159         //顯示下拉刷新樣式
160         mAuthors = new ArrayList<Author>();
161         //設置空數據
162         mAuthorListAdapter = new AuthorListAdapter(this, mAuthors);
163         mRecyclerView.setAdapter(mAuthorListAdapter);
164         getData(1, 10);
165     }
166 
167     /**
168      * 根據博主暱稱搜索博客
169      *
170      * @param name
171      */
172     public void getDataByName(String name) {
173         String url = "http://wcf.open.cnblogs.com/blog/bloggers/search?t=" + name;
174         StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
175             @Override
176             public void onResponse(String s) {
177                 try {
178                     ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
179                     List<Author> authors = AuthorListXmlParser.getListAuthor(inputStream, "utf-8");
180                     if (authors.size() != 0) {
181                         //清空以前的數據預防重複加載
182                         mAuthors.clear();
183                         for (Author author : authors) {
184                             mAuthors.add(author);
185                         }
186 
187                         if (mAuthorListAdapter == null) {
188                             mAuthorListAdapter = new AuthorListAdapter(SearchActivity.this, mAuthors);
189                             mRecyclerView.setAdapter(mAuthorListAdapter);
190                         } else {
191                             //通知adatper數據源更新
192                             mAuthorListAdapter.refreshData(mAuthors);
193                         }
194 
195                         materialDialog.dismiss();
196                     } else {
197                         //若是匹配不到關鍵字
198                         Toast.makeText(SearchActivity.this, "找不到相關用戶,請從新搜索", Toast.LENGTH_SHORT).show();
199                         materialDialog.dismiss();
200                     }
201                 } catch (XmlPullParserException e) {
202                     e.printStackTrace();
203                 } catch (IOException e) {
204                     e.printStackTrace();
205                 }
206             }
207         }, new Response.ErrorListener() {
208             @Override
209             public void onErrorResponse(VolleyError volleyError) {
210                 Toast.makeText(SearchActivity.this, volleyError.getMessage(), Toast.LENGTH_SHORT).show();
211             }
212         });
213 
214         VolleyRequestQueueManager.addRequest(request, "getAuthorList");
215 
216     }
217 
218 
219     /**
220      * 獲取推薦數據
221      *
222      * @param page
223      * @param num
224      */
225     public void getData(final int page, int num) {
226         this.currentPage = page;
227         String url = "http://wcf.open.cnblogs.com/blog/bloggers/recommend/" + page + "/" + num;
228         StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
229             @Override
230             public void onResponse(String s) {
231                 try {
232                     ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
233                     List<Author> authors = AuthorListXmlParser.getListAuthor(inputStream, "utf-8");
234                     if (page == 1) {
235                         //清空以前的數據預防重複加載
236                         mAuthors.clear();
237                     }
238                     for (Author author : authors) {
239                         mAuthors.add(author);
240                     }
241 
242                     if (mAuthorListAdapter == null) {
243                         mAuthorListAdapter = new AuthorListAdapter(SearchActivity.this, mAuthors);
244                         mRecyclerView.setAdapter(mAuthorListAdapter);
245                     } else {
246                         //通知adatper數據源更新
247                         mAuthorListAdapter.refreshData(mAuthors);
248                     }
249 
250                     isLoading = false;
251                     mBaseAttacher.setLoadMoreEnabled(true);
252                     myProgressBar.setVisibility(View.GONE);
253 
254                 } catch (XmlPullParserException e) {
255                     e.printStackTrace();
256                 } catch (IOException e) {
257                     e.printStackTrace();
258                 }
259             }
260         }, new Response.ErrorListener() {
261             @Override
262             public void onErrorResponse(VolleyError volleyError) {
263                 Toast.makeText(SearchActivity.this, volleyError.getMessage(), Toast.LENGTH_SHORT).show();
264             }
265         });
266 
267         VolleyRequestQueueManager.addRequest(request, "getAuthorList");
268 
269 
270     }
271 
272 }

這裏是博客列表的適配器類,和以前的博文列表同樣,咱們須要本身添加點擊監聽,再點擊Item項的時候將Blog對象傳遞:

  1 package com.lcw.rabbit.myblog.adapter;
  2 
  3 import android.content.Context;
  4 import android.content.res.Resources;
  5 import android.graphics.Bitmap;
  6 import android.graphics.BitmapFactory;
  7 import android.support.v7.widget.RecyclerView;
  8 import android.view.LayoutInflater;
  9 import android.view.View;
 10 import android.view.ViewGroup;
 11 import android.widget.ImageButton;
 12 import android.widget.TextView;
 13 
 14 import com.lcw.rabbit.myblog.R;
 15 import com.lcw.rabbit.myblog.entity.Author;
 16 import com.lcw.rabbit.myblog.utils.ImageCacheManager;
 17 import com.lcw.rabbit.myblog.utils.TimeUtil;
 18 import com.makeramen.roundedimageview.RoundedImageView;
 19 
 20 import java.util.List;
 21 
 22 /**
 23  * 推薦博主列表適配器
 24  * Created by Lichenwei
 25  * Date: 2015-08-16
 26  * Time: 22:34
 27  */
 28 public class AuthorListAdapter extends RecyclerView.Adapter<AuthorListAdapter.RecyclerViewViewHolder> {
 29 
 30     private Context mContext;
 31     private List<Author> mAuthors;
 32 
 33     public AuthorListAdapter(Context context, List<Author> authors) {
 34         this.mContext = context;
 35         this.mAuthors = authors;
 36     }
 37 
 38     /**
 39      * 設置新的數據源,提醒adatper更新
 40      *
 41      * @param authors
 42      */
 43     public void refreshData(List<Author> authors) {
 44         this.mAuthors = authors;
 45         this.notifyDataSetChanged();
 46     }
 47 
 48     /**
 49      * 自定義點擊回調接口
 50      */
 51     public interface RecyclerViewListener {
 52         void setOnclickListener(View view, String value);
 53     }
 54 
 55     private RecyclerViewListener mRecyclerViewListener;
 56 
 57     /**
 58      * 提供setter方法
 59      *
 60      * @param recyclerViewListener
 61      */
 62     public void setRecyclerViewListener(RecyclerViewListener recyclerViewListener) {
 63         this.mRecyclerViewListener = recyclerViewListener;
 64     }
 65 
 66 
 67     /**
 68      * 建立ViewHolder
 69      *
 70      * @param viewGroup
 71      * @param i
 72      * @return
 73      */
 74     @Override
 75     public RecyclerViewViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
 76         View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item_authorlist, viewGroup, false);
 77         return new RecyclerViewViewHolder(view);
 78     }
 79 
 80     /**
 81      * 根據資源ID返回Bitmap對象
 82      *
 83      * @param resId
 84      * @return
 85      */
 86     public Bitmap getBitmapFromRes(int resId) {
 87         Resources res = mContext.getResources();
 88         return BitmapFactory.decodeResource(res, resId);
 89 
 90     }
 91 
 92     /**
 93      * 綁定數據
 94      *
 95      * @param viewholder
 96      * @param i
 97      */
 98     @Override
 99     public void onBindViewHolder(RecyclerViewViewHolder viewholder, int i) {
100         //設置頭像
101         if (mAuthors.get(i).getAuthorPic() != null && !"".equals(mAuthors.get(i).getAuthorPic())) {
102             ImageCacheManager.loadImage(mAuthors.get(i).getAuthorPic(), viewholder.mUserhead, getBitmapFromRes(R.mipmap.avatar_default), getBitmapFromRes(R.mipmap.avatar_default));
103         } else {
104             viewholder.mUserhead.setImageResource(R.mipmap.avatar_default);
105         }
106         viewholder.mName.setText(mAuthors.get(i).getAuthorName());
107         viewholder.mUrl.setText(mAuthors.get(i).getAuthorUrl());
108         viewholder.mSum.setText(mAuthors.get(i).getBlogCount());
109         viewholder.mTime.setText(mAuthors.get(i).getUpdated());
110         //處理日期特殊格式
111         String date = TimeUtil.DateToChineseString(TimeUtil.ParseUTCDate(mAuthors.get(i).getUpdated()));
112         viewholder.mTime.setText(date);
113 
114         //設置點擊監聽
115         viewholder.itemView.setTag(i);
116         viewholder.mMore.setTag(i);
117         viewholder.itemView.setOnClickListener(new ItemClick());
118         viewholder.mMore.setOnClickListener(new ItemClick());
119     }
120 
121     @Override
122     public int getItemCount() {
123         return mAuthors.size();
124     }
125 
126     /**
127      * 自定義ViewHolder
128      */
129     public static class RecyclerViewViewHolder extends RecyclerView.ViewHolder {
130         private RoundedImageView mUserhead;
131         private TextView mName;
132         private TextView mUrl;
133         private TextView mTime;
134         private TextView mSum;
135         private ImageButton mMore;
136 
137         public RecyclerViewViewHolder(View view) {
138             super(view);
139             mUserhead = (RoundedImageView) view.findViewById(R.id.iv_userhead);
140             mName = (TextView) view.findViewById(R.id.tv_name);
141             mUrl = (TextView) view.findViewById(R.id.tv_url);
142             mTime = (TextView) view.findViewById(R.id.tv_time);
143             mSum = (TextView) view.findViewById(R.id.tv_sum);
144             mMore = (ImageButton) view.findViewById(R.id.ib_more);
145 
146         }
147 
148     }
149 
150 
151     /**
152      * 點擊事件實現類
153      */
154     public class ItemClick implements View.OnClickListener {
155         @Override
156         public void onClick(View v) {
157             if (mRecyclerViewListener != null) {
158                 mRecyclerViewListener.setOnclickListener(v, String.valueOf(v.getTag()));
159             }
160         }
161     }
162 }

 

二、關於博客首頁的實現:

  頁面的總體結構仍是相似,上半部分是信息展現,下半部分是一個RecyclerView列表,列表項裏面的佈局和相關操做下拉刷新上拉加載,咱們均可以複用以前首頁的博文展現,這裏只不過是數據源的不一樣。

  因爲咱們在搜索頁面點擊Item項的時候傳遞了Blog對象,咱們就能夠根據做者名來獲取關於博客做者的一些信息,這裏是接口:http://wcf.open.cnblogs.com/blog/u/{BLOGAPP}/posts/{PAGEINDEX}/{PAGESIZE} {BLOGAPP}表明做者的帳號,{PAGEINDEX}表明頁碼,{PAGESIZE}表明每頁的數據條數。

  重複的東西這裏就再也不多說了,這裏講點新引入的東西,細心的朋友可能有發現當咱們更新數據(上拉刷新,下拉加載)的時候,列表底部有個彈出提示框,這個就是安卓5.0用來取代Toast的SnackBar:

1             //snackbar提醒
2                     Snackbar snackbar = Snackbar.make(mToolbar,"當前更新"+mBlogs.size()+"條博客信息",Snackbar.LENGTH_LONG);
3                     snackbar.show();

用法很簡單,相似於Toast,不過不同的是,它是具備交互效果的,也就是說咱們能夠在Snackbar上添加點擊事件,關於Snackbar的詳細用法,有興趣的朋友本身網上找找資料吧。

  而後再來講下關於這個FAB(Floating Action Button)的移動效果,這裏我採用的是共享元素移動,因爲咱們的博文詳情頁和博主詳情頁都具備這個控件,因此咱們在切換Activity的時候能夠進行動畫設置,這裏makeSceneTransitionAnimation的第二個參數爲共享View,第三個參數爲標誌參數要與xml裏的transitionName保持一致。

1     android:transitionName="fab"
1  startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(AuthorActivity.this, mFloatingActionButton, "fab").toBundle());

 

好了,今天先寫到這裏,改天繼續更新,有什麼建議或疑問,能夠在文章評論給我留言。

 

做者:李晨瑋
出處:http://www.cnblogs.com/lichenwei/本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,往後必有一番做爲!旁邊有「推薦」二字,你就順手把它點了吧,相得準,我分文不收;相不許,你也好回來找我!

相關文章
相關標籤/搜索