你的位置:首页 > Java教程

[Java教程]安卓开发笔记——打造属于自己的博客园APP(四)


  在上篇文章《安卓开发笔记——打造属于自己的博客园APP(三)》中,我们对博客文章的详情页和评论页进行了实现,慢慢的一个APP已经出现雏形了,当然这只是完成了"表面效果",要真正做好一个APP并不是一件很轻松的事情,有很多细节需要我们一点一滴的去完善。

  好了,来讲下今天要完成的效果,在优化了之前部分代码的前提下,今天来说下关于博客搜索和博客详情页的实现,依旧国际惯例,来看下效果图:(动态图片比较大,加载需要点时间)

  效果比较简单,很多东西我们还是可以复用之前的代码,毕竟这种列表长得都差不多,然后大致功能基本完成了,从下篇文章开始可以引入我们的数据库了,开始实现缓存操作。

 

1、关于搜索页面的实现:

  很简单,分成两部分,上面一个EditText,下面一个RecyclerView,当我们刚进入页面的时候默认展示博客园给我们的推荐用户,当搜索的时候更新列表数据。

  这里是关于博客园推荐用户的接口: http://wcf.open.cnblogs.com/blog/bloggers/recommend/{PAGEINDEX}/{PAGESIZE} {PAGEINDEX}代表页码,{PAGESIZE}代表每页展示的条数

这里是搜索页面的主布局文件:

 1 <LinearLayout ="http://schemas.android.com/apk/res/android" 2   ="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   <LinearLayout12     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     <RelativeLayout21       android:layout_width="match_parent"22       android:layout_height="40dp"23       android:background="@drawable/bg_search"24       android:gravity="center_vertical">25 26       <ImageButton27         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       <EditText34         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   <FrameLayout44     android:layout_width="match_parent"45     android:layout_height="match_parent">46 47     <android.support.v7.widget.RecyclerView48       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.MyProgressBar55       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.

这里是下面RecyclerView列表的Item布局:

 1 <android.support.v7.widget.CardView ="http://schemas.android.com/apk/res/android" 2   ="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.

这里是Item布局的详细:

 1 <LinearLayout ="http://schemas.android.com/apk/res/android" 2   ="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.

关于博客园推荐博客的接口数据

 1 package com.lcw.rabbit.myblog.parser; 2  3 import com.lcw.rabbit.myblog.entity.Author; 4  5 import org. 6 import org. 7 import org. 8  9 import java.io.IOException; 10 import java.io.InputStream; 11 import java.util.ArrayList; 12 import java.util.List; 13  14 /** 15  * 对博客作者(列表) 16  * Created by Lichenwei 17  * Date: 2015-08-17 18  * Time: 13:32 19 */ 20 public class AuthorList 21  22  23   /** 24    * 用于解析博客作者(列表)的 25    * 26    * @param inputStream 27    * @param encode 28    * @return 29    * @throws  30    * @throws IOException 31   */ 32   public static List<Author> getListAuthor(InputStream inputStream, String encode) throws  33  34     List<Author> mAuthors = null; 35     Author mAuthor = null; 36  37     //获取 38       39      factory.newPullParser(); 40     parser.setInput(inputStream, encode); 41     //获取解析事件 42     int eventType = parser.getEventType(); 43     //当 44     while (eventType !=  45       switch (eventType) { 46         //解析根标签的时候,实例化集合 47         case  48           mAuthors = new ArrayList<Author>(); 49           mAuthor = new Author(); 50  51           break; 52         case  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  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}代表作者名(多关键字匹配),搜索到的

 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.AuthorList 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. 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       @Override100       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       @Override110       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     //ToolBar130     mToolbar = (Toolbar) findViewById(R.id.activity_toolbar);131     setSupportActionBar(mToolbar);132     //需要放在setSupportActionBar后设置133     mToolbar.setNavigationOnClickListener(new View.OnClickListener() {134       @Override135       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 name171   */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       @Override176       public void onResponse(String s) {177         try {178           ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());179           List<Author> authors = AuthorList);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 (202           e.printStackTrace();203         } catch (IOException e) {204           e.printStackTrace();205         }206       }207     }, new Response.ErrorListener() {208       @Override209       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 page223    * @param num224   */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       @Override230       public void onResponse(String s) {231         try {232           ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());233           List<Author> authors = AuthorList);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 (255           e.printStackTrace();256         } catch (IOException e) {257           e.printStackTrace();258         }259       }260     }, new Response.ErrorListener() {261       @Override262       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   @Override122   public int getItemCount() {123     return mAuthors.size();124   }125 126   /**127    * 自定义ViewHolder128   */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     @Override156     public void onClick(View v) {157       if (mRecyclerViewListener != null) {158         mRecyclerViewListener.setOnclickListener(v, String.valueOf(v.getTag()));159       }160     }161   }162 }

 

2、关于博客首页的实现:

  页面的整体结构还是类似,上半部分是信息展示,下半部分是一个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,第三个参数为标志参数要与

1   android:transitionName="fab"

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

 

好了,今天先写到这里,改天继续更新,有什么建议或疑问,可以在文章评论给我留言。

 

作者:李晨玮
出处:http://www.cnblogs.com/lichenwei/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!