在上一篇文章《安卓开发笔记——打造属于自己的博客园APP(一)》中,我们基本上实现了博客园的主体UI框架(后面可能会有些小变化,等遇到了再说)。今天来讲讲博客园首页模块的大体实现,国际惯例,先来看下效果图:

整体UI效果:

安卓开发笔记——打造属于自己的博客园APP(二)

下拉刷新和上拉加载的动画效果:

安卓开发笔记——打造属于自己的博客园APP(二)  安卓开发笔记——打造属于自己的博客园APP(二)

  在上篇文章中,我们定义的Tabs主题文字分别是(首页,精华,候选,推荐),这边的命名我是根据博客园网站首页的栏目来命名的,那时候我还没仔细看过博客园的开放接口,后来才发现原来博客园没有对应开放这些栏目的接口,博客园只开放了(文章列表,48小时阅读排行,10天内推荐排行,推荐博客列表)等接口,所以我对应的在Tabs标签主题上改动了下文字。由于是随性开发,没有做过多的前期准备,嘿嘿O(∩_∩)O~

  PS:其实不按照接口来也是可以的,我们可以采用数据采集的方式来获取数据,有兴趣的朋友可以看看我之前写的一些列关于JAVA采集数据的文章:

  《基于Java数据采集入库(一)》:http://www.cnblogs.com/lichenwei/p/3904715.html

  《基于Java数据采集入库(二)》:http://www.cnblogs.com/lichenwei/p/3905370.html

  《基于Java数据采集入库(三)》:http://www.cnblogs.com/lichenwei/p/3907007.html

  《基于Java的数据采集(终结篇)》:http://www.cnblogs.com/lichenwei/p/3910492.html

 

  现在已经实现的效果:主UI效果的基本搭建,网络框架的搭建,各博客列表页面的展示包括更新效果,对图片做了三级缓存处理(后面会把文章,新闻做成离线闪存,实现无网络也能照常浏览)等,功能还有很多,慢慢去实现,然后对各细节的优化也会慢慢迭代去完成。

  好了,进入主题,由于文章篇幅问题,我这里只会对第一个页面进行讲解,其他大同小异了。

 

1、解析XML数据

这里是博客园对博客内容的开放接口:http://wcf.open.cnblogs.com/blog/help

安卓开发笔记——打造属于自己的博客园APP(二)

  很无奈的发现,博客园的接口是用XML编写的,需要我们去解析XML,挺麻烦的,如果是Json不管在效率上或是我们代码编写上都会来得方便许多。

下面是对首页博文列表:http://wcf.open.cnblogs.com/blog/help/operations/GetSitHomeRecentPagedPosts的XML解析代码

其中第一个参数PAGEINDEX代表页数(默认1),第二个参数PAGESIZE代表每页显示的文章条数(默认20)

  1 package com.lcw.rabbit.myblog.parser;
  2 
  3 import com.lcw.rabbit.myblog.entity.Blog;
  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 BlogsListXmlParser {
 21 
 22 
 23     /**
 24      * 用于解析博客列表的xml,返回Blog的List集合对象
 25      *
 26      * @param inputStream
 27      * @param encode
 28      * @return
 29      * @throws XmlPullParserException
 30      * @throws IOException
 31      */
 32     public static List<Blog> getListBlogs(InputStream inputStream, String encode) throws XmlPullParserException, IOException {
 33 
 34         List<Blog> mBlogs = null;
 35         Blog mBlog = 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                     mBlogs = new ArrayList<Blog>();
 49                     mBlog = new Blog();
 50 
 51                     break;
 52                 case XmlPullParser.START_TAG:
 53                     //当解析到entry标签的时候,实例化Blog对象
 54                     if ("entry".equals(parser.getName())) {
 55                         mBlog = new Blog();
 56                     }
 57                     if ("id".equals(parser.getName())) {
 58                         parser.next();
 59                         mBlog.setBlogId(parser.getText());
 60                     } else if ("title".equals(parser.getName())) {
 61                         parser.next();
 62                         //特殊处理
 63                         if (!"博客园".equals(parser.getText())) {
 64                             mBlog.setBlogTitle(parser.getText());
 65                         }
 66                     } else if ("summary".equals(parser.getName())) {
 67                         parser.next();
 68                         mBlog.setBlogSummary(parser.getText());
 69                     } else if ("published".equals(parser.getName())) {
 70                         parser.next();
 71                         mBlog.setBlogPublished(parser.getText());
 72                     } else if ("name".equals(parser.getName())) {
 73                         parser.next();
 74                         mBlog.setAuthorName(parser.getText());
 75                     } else if ("uri".equals(parser.getName())) {
 76                         parser.next();
 77                         mBlog.setAuthorUri(parser.getText());
 78                     } else if ("avatar".equals(parser.getName())) {
 79                         parser.next();
 80                         mBlog.setAuthorAvatar(parser.getText());
 81                     } else if ("link".equals(parser.getName())) {
 82                         //特殊处理
 83                         if (parser.getAttributeName(0).equals("rel")) {
 84                             mBlog.setBlogLink(parser.getAttributeValue(1));
 85                         }
 86                     } else if ("diggs".equals(parser.getName())) {
 87                         parser.next();
 88                         mBlog.setBlogDiggs(parser.getText());
 89                     } else if ("views".equals(parser.getName())) {
 90                         parser.next();
 91                         mBlog.setBlogViews(parser.getText());
 92                     } else if ("comments".equals(parser.getName())) {
 93                         parser.next();
 94                         mBlog.setBlogComments(parser.getText());
 95                     }
 96                     break;
 97                 case XmlPullParser.END_TAG:
 98                     //当解析到entry标签结束的时候添加入Blogs集合,清空Blog对象
 99                     if ("entry".equals(parser.getName())) {
100                         mBlogs.add(mBlog);
101                         mBlog = null;
102                     }
103                     break;
104 
105             }
106             //手动跳转第一次遍历
107             eventType = parser.next();
108         }
109 
110 
111         return mBlogs;
112 
113     }
114 
115 }

  在JAVA中解析XML一般有三种方式(SAX,DOM,PULL),上面代码采用的是最后一种PULL方式的解析,前面两种SAX,DOM一般用于JAVAEE里,PULL方式的解析相对前两者来得比较轻量,安卓内部对XML的解析也是采用的PULL,所以没必要引入新的JAR包,关于这三种方式的解析,这里就不再多说了,不是今天的重点。(PS:之前一直做的是Json解析,XML解析几乎没用过,可能大家有更好的更有效率的解析方式,如果有可以在文章评论里帮我指点下迷津)。

  好了,上面的代码已经对XML解析封装完成,我们只需要传入一个输入流和编码格式,就可以把我们想要的数据装在到List集合了。

这里是List集合里的实体类:

  1 package com.lcw.rabbit.myblog.entity;
  2 
  3 /**
  4  * 博客实体类
  5  * Created by Lichenwei
  6  * Date: 2015-08-17
  7  * Time: 13:34
  8  */
  9 public class Blog {
 10     //文章id
 11     private String blogId;
 12     //文章标题
 13     private String blogTitle;
 14     //文章概要
 15     private String blogSummary;
 16     //更新时间
 17     private String blogPublished;
 18     //博主昵称
 19     private String authorName;
 20     //博主头像地址
 21     private String authorAvatar;
 22     //博主博客地址
 23     private String authorUri;
 24     //博文链接
 25     private String blogLink;
 26     //博文评论数
 27     private String blogComments;
 28     //博文浏览数
 29     private String blogViews;
 30     //博文推荐数
 31     private String blogDiggs;
 32 
 33     public Blog() {
 34     }
 35 
 36     public Blog(String blogId, String blogTitle, String blogSummary, String blogPublished, String authorName, String authorAvatar, String authorUri, String blogLink, String blogComments, String blogViews, String blogDiggs) {
 37         this.blogId = blogId;
 38         this.blogTitle = blogTitle;
 39         this.blogSummary = blogSummary;
 40         this.blogPublished = blogPublished;
 41         this.authorName = authorName;
 42         this.authorAvatar = authorAvatar;
 43         this.authorUri = authorUri;
 44         this.blogLink = blogLink;
 45         this.blogComments = blogComments;
 46         this.blogViews = blogViews;
 47         this.blogDiggs = blogDiggs;
 48     }
 49 
 50     public String getBlogId() {
 51         return blogId;
 52     }
 53 
 54     public void setBlogId(String blogId) {
 55         this.blogId = blogId;
 56     }
 57 
 58     public String getBlogTitle() {
 59         return blogTitle;
 60     }
 61 
 62     public void setBlogTitle(String blogTitle) {
 63         this.blogTitle = blogTitle;
 64     }
 65 
 66     public String getBlogSummary() {
 67         return blogSummary;
 68     }
 69 
 70     public void setBlogSummary(String blogSummary) {
 71         this.blogSummary = blogSummary;
 72     }
 73 
 74     public String getBlogPublished() {
 75         return blogPublished;
 76     }
 77 
 78     public void setBlogPublished(String blogPublished) {
 79         this.blogPublished = blogPublished;
 80     }
 81 
 82     public String getAuthorName() {
 83         return authorName;
 84     }
 85 
 86     public void setAuthorName(String authorName) {
 87         this.authorName = authorName;
 88     }
 89 
 90     public String getAuthorAvatar() {
 91         return authorAvatar;
 92     }
 93 
 94     public void setAuthorAvatar(String authorAvatar) {
 95         this.authorAvatar = authorAvatar;
 96     }
 97 
 98     public String getAuthorUri() {
 99         return authorUri;
100     }
101 
102     public void setAuthorUri(String authorUri) {
103         this.authorUri = authorUri;
104     }
105 
106     public String getBlogLink() {
107         return blogLink;
108     }
109 
110     public void setBlogLink(String blogLink) {
111         this.blogLink = blogLink;
112     }
113 
114     public String getBlogComments() {
115         return blogComments;
116     }
117 
118     public void setBlogComments(String blogComments) {
119         this.blogComments = blogComments;
120     }
121 
122     public String getBlogViews() {
123         return blogViews;
124     }
125 
126     public void setBlogViews(String blogViews) {
127         this.blogViews = blogViews;
128     }
129 
130     public String getBlogDiggs() {
131         return blogDiggs;
132     }
133 
134     public void setBlogDiggs(String blogDiggs) {
135         this.blogDiggs = blogDiggs;
136     }
137 
138     @Override
139     public String toString() {
140         return "Blog{" +
141                 "blogId='" + blogId + '\'' +
142                 ", blogTitle='" + blogTitle + '\'' +
143                 ", blogSummary='" + blogSummary + '\'' +
144                 ", blogPublished='" + blogPublished + '\'' +
145                 ", authorName='" + authorName + '\'' +
146                 ", authorAvatar='" + authorAvatar + '\'' +
147                 ", authorUri='" + authorUri + '\'' +
148                 ", blogLink='" + blogLink + '\'' +
149                 ", blogComments='" + blogComments + '\'' +
150                 ", blogViews='" + blogViews + '\'' +
151                 ", blogDiggs='" + blogDiggs + '\'' +
152                 '}';
153     }
154 }
Blog

相关文章: