仿知乎日报第九篇:为首页以及其他12个页面从网上加载数据分析

一.


         如上图所示,MainActivity的两个部分LeftFragment和MainFragment,这两个部分结构搭建好了,布局也有了, MainFragment中的ViewPager要显示的13个页面控件虽然也有了,但是像首页中的ViewPager,TextView,ListView其他页面中的ImageView,TextView,ListView等控件中还没有真正的数据,这些数据我们要从网络上拿下来,拿过来的数据是json格式,我们要用Gson把这些数据解析出来。

         还记得我们在BasePage页面创建了一个抽象方法initData()吗?各个子页面继承了BasePage,必须要实现这个方法,在这个方法里面各自从网络拿到自己的数据,然后再解析数据,把数据放到相应的控件上面。

         那initData()方法是什么时候调用的呢?想想看,如果我们把initData()方法放在BasePage的构造方法中,那么MainFragment对象创建的时候会创建13个页面,这个时候会一下子调用13个页面的initData()方法,一下子把所有页面的数据都下载下来了。这个肯定不合适。那么什么时候调用呢?当然是切换到什么页面,调用该页面的initData()方法从网络加载数据。而切换页面的时候肯定会调用Adapter中的instantiateItem ()方法。在这个方法中调用13个页面的initData()方法。

         我在网上找到一个知乎日报的数据接口,地址是https://github.com/izzyleung/ZhihuDailyPurify/wiki/%E7%9F%A5%E4%B9%8E%E6%97%A5%E6%8A%A5-API-%E5%88%86%E6%9E%90,它返回的数据都是Json格式的。你们好好读一下接口文档,分析下怎么调用自己所需要的数据。

         我们现在需要13个页面的数据,据分析,首页数据的URL:  http://news-at.zhihu.com/api/4/news/latest。其他12个主题日报的URL:http://news-at.zhihu.com/api/4/theme/(主题日报的id),例如,http://news-at.zhihu.com/api/4/theme/13可以拿到日常心理学的数据,这里的13为日常心理学的id。

         这个id我是通过http://news-at.zhihu.com/api/4/themes这个地址拿到,拿到之后放到HiJson这个软件里面,会把拿到的Json数据结构化,如下图所示:


 

         所以我们看到用户推荐日报的id是12,那么拿到它的数据的url为http://news-at.zhihu.com/api/4/theme/12,其他主题日报的url只要改变一下id就可以了。

因为这12个主题日报所对应的id不会变,为了少访问一次网络,少解析一次数据,所以我把这些id拿出来,按菜单区ListView各个item(日常心理学,用户推荐日报,电影日报等)的顺序放在数组里面。如下图:


         在MainFragment的ViewPager中的instantiateItem()方法中调用BasePage的initData()方法,如果位置是首页,传入空字符串。如果是其他12个页面,传入对应的id。

         总结一下,首页的url和其他页面的url完全不一样,再加上我们前面说的首页的布局也和其他页面的布局不同,所以这里我们分为两个部分来处理。第一个部分当然是首页单独为一部分。首页页面继承BasePage实现它的initData()方法从网络拿到数据,解析后放到想要的控件上面。第二个部分是12个页面,它们布局一模一样,从网络拿到的数据结构也是一模一样,url也差不多,只是后面的id不一样。所以我们可以把这些一样的内容抽取出来,放在同一个类里面。我们将会创建ThemeDailyBasePage这个类,它继承于BasePage,实现initData()方法,在这个方法中也是从网络中拿到数据,解析后放到相应的控件上面。然后12页面分别继承于ThemeDailyBasePage这个类,12个页面相似的加载数据,为组件填充数据的逻辑都在ThemeDailyBasePage这个类中实现了。12页面中只需要改一下标题就可以了。

         二.现在我们用代码来解释上述过程

1.MainFragment中,12个主题日报的id按顺序创建数组。在Adapter的instantiateItem()方法中调用BasePage的initData()方法,传入相应的id

public class MainFragment extends BaseFragment {
//  13个页面的集合
    private List<BasePage> allPages = new ArrayList<BasePage>();
    private MyViewPager  mViewPager;
//  12个主题日报的id,例如日常心理学的id为13,用户推荐日报对应的id为12,
//  后面获取相应的主题日报的url为http://news-at.zhihu.com/api/4/theme/  + id
//  例如要拿到日常心理学日报的数据url为http://news-at.zhihu.com/api/4/theme/13
    private String[]     themeDailyNumber  = { "13", "12", "3", "11", "4",
           "5", "6", "10", "2", "7", "9", "8" };
    private int              selectedPosition = 0;
......
//  根据传进来的位置编号在13个页面之间切换
    public void switchPage(int position){
//     selectedPosition成员变量记录传进来的编号
       this.selectedPosition = position;
//     这个方法会调用Adapter中的getView方法
       mViewPager.setCurrentItem(position);
      
    }
   
    private class MyAdapter extends PagerAdapter{
 
       @Override
       public int getCount() {
           // TODO自动生成的方法存根
           return allPages.size();
       }
 
       @Override
       public boolean isViewFromObject(View arg0, Object arg1) {
           // TODO自动生成的方法存根
           return arg0 == arg1;
       }
 
       @Override
       public void destroyItem(ViewGroup container, int position, Objectobject) {
           // TODO自动生成的方法存根
           container.removeView((View) object);
       }
 
       @Override
       public Object instantiateItem(ViewGroup container, int position) {
//         根据position拿到相应的页面
           BasePage selectedPage = allPages.get(position);
//         拿到相应页面的View,加到容器中
           container.addView(selectedPage.getRoot());
//         在这里调用initData()方法加载13个页面的数据。
//         如果selectedPosition为0,则为首页
//         如果selectedPosition不为0,则是其他12个主题日报,把对应的id传进去
           if (selectedPosition != 0) {
              selectedPage.initData(themeDailyNumber[selectedPosition -1]);
           }else {
              selectedPage.initData("");
           }
          
           return selectedPage.getRoot();
       }
      
    }
 
}


2.首页实现initData()方法,在该方法中从网络中加载数据,解析数据,把数据放到相应的控件上(具体的后面再讲)

public class HomeBasePage extends BasePage {
 
   
 
    public HomeBasePage(MainActivity mainActivity) {
       super(mainActivity);
       // TODO自动生成的构造函数存根
    }
// themeDailyNumber参数是主题日报的的id,首页中不需要,可以忽略
    @Override
    public void initData(String themeDailyNumber) {
      
 
    }


3. ThemeDailyBasePage实现initData()方法,在该方法中从网络中加载数据,解析数据,把数据放到相应的控件上(具体的后面再讲)

 

public class HomeBasePage extends BasePage {
 
   
 
    public HomeBasePage(MainActivity mainActivity) {
       super(mainActivity);
       // TODO自动生成的构造函数存根
    }
// themeDailyNumber参数是主题日报的的id,首页中不需要,可以忽略
    @Override
    public void initData(String themeDailyNumber) {
      
 
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值