1.效果预览

1.1.网站列表实际界面

  

1.2.注意这个界面没有继承SimpleRefreshRecycleFragment

  前面的话题和新闻继承了SimpleRefreshRecyclerFragment

  但是网站的页面继承了第二等级的RefreshRecyclerFragment

  区别就在于:

    第三等级的SimpleRefreshRecyclerFragment具有快速回到顶部的功能。

  其实SitesListFragment也有快速回到顶部的功能,不过和前两个不太一样。

  因为布局的方式不一样,

  SitesListFragment要获取一个GridLayoutManager

  但是前两个要获取一个自定义的LinearLayoutManager

2.SitesListFragment整体分析

2.1.布局依旧是和前两个一样的

  

  这是RefreshRecyclerFragment中定义的布局

  所以可以知道布局是一样的

  那么RecyclerView是支持多列分布的。

2.2.函数分布情况

  

  除了newInstance函数和convertData是自己新建的函数外,其他都是override基类中的方法的。

2.3.SitesListFragment源代码

/*
* Copyright 2017 GcsSloop
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Last modified 2017-04-09 14:32:41
*
* GitHub: https://github.com/GcsSloop
* Website: http://www.gcssloop.com
* Weibo: http://weibo.com/GcsSloop
*/ package com.gcssloop.diycode.fragment; import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView; import com.gcssloop.diycode.fragment.base.RefreshRecyclerFragment;
import com.gcssloop.diycode.fragment.bean.SiteItem;
import com.gcssloop.diycode.fragment.bean.SitesItem;
import com.gcssloop.diycode.fragment.provider.SiteProvider;
import com.gcssloop.diycode.fragment.provider.SitesProvider;
import com.gcssloop.diycode_sdk.api.sites.bean.Sites;
import com.gcssloop.diycode_sdk.api.sites.event.GetSitesEvent;
import com.gcssloop.diycode_sdk.log.Logger;
import com.gcssloop.recyclerview.adapter.multitype.HeaderFooterAdapter; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; /**
* 首页 sites 列表
*/
public class SitesListFragment extends RefreshRecyclerFragment<Sites, GetSitesEvent> { public static SitesListFragment newInstance() {
Bundle args = new Bundle();
SitesListFragment fragment = new SitesListFragment();
fragment.setArguments(args);
return fragment;
} @Override public void initData(HeaderFooterAdapter adapter) {
setLoadMoreEnable(true);
List<Serializable> sitesList = mDataCache.getSitesItems();
if (sitesList != null) {
Logger.e("sites : " + sitesList.size());
mAdapter.addDatas(sitesList);
setLoadMoreEnable(false);
} else {
loadMore();
}
} @Override
protected void setAdapterRegister(Context context, RecyclerView recyclerView,
HeaderFooterAdapter adapter) {
mAdapter.register(SiteItem.class, new SiteProvider(getContext()));
mAdapter.register(SitesItem.class, new SitesProvider(getContext()));
} @NonNull @Override protected RecyclerView.LayoutManager getRecyclerViewLayoutManager() {
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (mAdapter.getFullDatas().get(position) instanceof SiteItem) ? 1 : 2;
}
});
return layoutManager;
} @NonNull @Override protected String request(int offset, int limit) {
return mDiycode.getSites();
} @Override protected void onRefresh(GetSitesEvent event, HeaderFooterAdapter adapter) {
toast("刷新成功");
convertData(event.getBean());
} @Override protected void onLoadMore(GetSitesEvent event, HeaderFooterAdapter adapter) {
toast("加载成功");
convertData(event.getBean());
} @Override protected void onError(GetSitesEvent event, String postType) {
toast("获取失败");
} // 转换数据
private void convertData(final List<Sites> sitesList) {
ArrayList<Serializable> items = new ArrayList<>();
for (Sites sites : sitesList) { items.add(new SitesItem(sites.getName())); for (Sites.Site site : sites.getSites()) {
items.add(new SiteItem(site.getName(), site.getUrl(), site.getAvatar_url()));
} if (sites.getSites().size() % 2 == 1) {
items.add(new SiteItem("", "", ""));
}
} mAdapter.clearDatas();
mAdapter.addDatas(items);
mDataCache.saveSitesItems(items);
setLoadMoreEnable(false);
}
}

3.SitesListFragment局部分析

3.1.新建一个实例

  

  这个不解释了,args其实没有数据,可能是为了方便,直接copy的。

3.2.初始化initData

  这是基类中最后执行的方法。

  

  这里的作用:判断缓存中有没有网站数据。如果有,直接加到adapter中,如果没有执行RefreshRecyclerFragment

        中的loadMore()方法,loadMore主要是进行request请求,然后确定请求状态数据等。

3.3.注册数据类型

  

  这里和其他不一样,这里注册了两个类,所以了解一下这两个类。

  SiteItem==>

  

  然后是SitesItem==>

  

  SiteItem有:name,url,avater_url

  SitesItem有:name

  都是自定义的Bean类。

3.4.获取布局管理器

  

  这里的布局采用了GridLayoutManager==>格子分布,包括两列。

  也许这里才是关键的布局设置。

3.5.请求函数

  

  获取网站数据。

3.6.刷新数据

  

  这里调用BaseFragment中的toast函数

  然后调用convertData函数

  

  终于理解了。这个items其实是所有的站点的集合。

  因为这个SitesListFragment分了几个大模块。

  每个模块中可能是奇数个,如果是奇数个,就添加一个空的接下去。

  其中每个模块也是用了一个for循环遍历了sites中的getSites。

  所以这个sitesList就是遍历模块的种类。

  然后这个sites.getSites就是遍历每一个模块中的站点。

  

3.7. 加载更多

  

  同样调用了数据转换的函数。

3.8.获取失败

    

4.总结一下

4.1.懂得这个SiteItem和SiteItems的区别,其实这是两个不同的类,看到实际的界面之后理解了。因为首先有多个模块。

  然后模块中是具体的某些站点,这个站点其实就是SiteItem包括了名字,url,头像,这个模块其实就是SiteItems

  仅仅展示一些名称就好,类别名称。

4.2.这里的初始化数据要理解一下,这里首先从缓存中得到一个sitesList,其实这个sitesList就是所有的站点+模块类别,

  因为这两个类很相似,一个叫做SiteItem,一个叫做SitesItem,在注册数据类型的时候,应该就是如果数据对应

  的是SiteItem,采用某一种布局,然后如果数据对应是SitesItem,就采用另外一种布局。

4.3.在关键函数convertData数据转换中,首先就变量模块个数,每个模块都加到一个ArrayList<Serializable>,很明

  显,SitesItem和SiteItem是不同类型的,但是都实现Serializable,所以都可以采用items.add的方式添加到这个

  集合中。值得注意的是,如果某个类别有奇数个,那么用一个空的填充到尾巴。

4.4.然后是一个getRecyclerViewLayoutManager函数,因为这个SiteListFragment没有继承第三等级的封装类,所以

  要自己写一个获取布局管理器的函数。这里将布局分成了2部分了,然后调用了一个setSpanSizeLookup来判断

  应该执行那个布局。以后再详细了解。

Diycode开源项目 SitesListFragment分析的更多相关文章

  1. Diycode开源项目 BaseApplication分析+LeakCanary第三方+CrashHandler自定义异常处理

    1.BaseApplication整个应用的开始 1.1.看一下代码 /* * Copyright 2017 GcsSloop * * Licensed under the Apache Licens ...

  2. DiyCode开源项目 BaseActivity 分析

    1.首先将这个项目的BaseActivity源码拷贝过来. /* * Copyright 2017 GcsSloop * * Licensed under the Apache License, Ve ...

  3. Diycode开源项目 MainActivity分析

    1.分析MainActivity整体结构 1.1.首先看一下这个界面的整体效果. 1.2.活动源代码如下 /* * Copyright 2017 GcsSloop * * Licensed under ...

  4. Diycode开源项目 ImageActivity分析

    1.首先看一下效果 1.1做成了一个GIF 1.2.我用格式工厂有点问题,大小无法调到手机这样的大小,目前还没有解决方案. 1.3.网上有免费的MP4->GIF,参考一下这个网站吧. 1.4.讲 ...

  5. Diycode开源项目 UserActivity分析

    1.效果预览 1.1.实际界面预览 1.2. 这是MainActivity中的代码 这里执行了跳转到自己的用户界面的功能. 1.3.点击头像或者用户名跳转到别人的页面 UserActivity的结构由 ...

  6. Diycode开源项目 TopicContentActivity分析

    1.效果预览以及布局分析 1.1.实际效果预览 左侧话题列表的布局是通过TopicProvider来实现的,所以当初分析话题列表就没有看到布局. 这里的话题内容不是一个ListView,故要自己布局. ...

  7. Diycode开源项目 LoginActivity分析

    1.首先看一下效果 1.1.预览一下真实页面 1.2.分析一下: 要求输入Email或者用户名,点击编辑框,弹出键盘,默认先进入输入Email或用户名编辑框. 点击密码后,密码字样网上浮动一段距离,E ...

  8. DiyCode开源项目 AboutActivity分析

    1.首先看一下效果 这是手机上显示的效果: 1.1首先是一个标题栏,左侧一个左箭头,然后一个图标. 1.2然后下方是一个可以滑动的页面. 1.3分成了7个部分. 1.4DiyCode的图标. 1.5然 ...

  9. DiyCode开源项目 TopicActivity 分析

    1.首先看看TopActivity效果.    2.TopicActivity是一个继承BaseActivity的.前面分析过BaseActivity了.主要有一个标题栏,有返回的图标. 3.贴一下T ...

随机推荐

  1. PHP underlying structure

    http://www.phpinternalsbook.com/classes_objects/magic_interfaces_comparable.html

  2. (C# 基础) 接口

    接口是表示一组函数成员,而不实现成员的引用类型.类和结构可以实现接口. 例如BCL声明了一个叫做IComparable的接口,包含了一个CompareTo方法, 但没有实现其方法,用“:”结尾. pu ...

  3. Spring Cloud程序报错总结

    1.com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: 原因如下: 在默认设置下,Eureka服务 ...

  4. UESTC 757 棋盘

    虽然是水题,但是还是很interesting的.(大概就是我最晚出这个题了... 博弈感觉就是靠yy能力啊.这题是对称性. 最后的必败态是白色格子对称的,一旦对称形成,对手怎么选,跟随就好,对手无法摆 ...

  5. POJ - 3109 Inner Vertices

    不存在-1的情况,而且最多一轮就结束了.如果新增加的黑点v0会产生新的黑点v1,那么v0和v1肯定是在一条轴上的,而原来这条轴上已经有黑点了. 离散以后扫描线统计,往线段上插点,然后查询区间上点数. ...

  6. 【[TJOI2017]DNA】

    [题目][https://www.lydsy.com/JudgeOnline/problem.php?id=4892] 好像用\(SAM\)做的都是\(dfs\)啊 其实这里也是搜索 如果用\(SAM ...

  7. 如何将Win7做为NTP服务器

    1. 修改注册表项    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer   ...

  8. FTP服务安装及使用

    准备工作:一台服务器.我这里使用的是阿里云的ECS. 环境使用的是:windows 2008 r2 用途:FTP是用来进行文件传输的,我们可以把这个目录在IIS上配置成发布的网站,我们在本地只用把我们 ...

  9. using System.Security.Cryptography

    这个命名空间主要是用来进行加密的一些类. 加密服务: 公共网络(如 Internet)不提供实体之间安全通信的方式. 此类网络上的通信易被读取或甚至被未经授权的第三方修改. 加密有助于防止数据被查看, ...

  10. es6-promise.auto.js

    使用sweetalert2的IE浏览器报错,导入文件 链接:https://pan.baidu.com/s/1mOcsN_o8m-7I7Rej1NPkiw 提取码:9xsj