1.以新闻页中的段子数据显示为例

1.1.首先执行InitApp==>SplashActivity。

  因为在AndroidManifest.xml中定义了一个<intent-filter>中有定义启动页

1.2.然后SplashActivity==>MainActivity。

  这是是intent的跳转。

1.3.然后执行MainActivity中的onCreate==>执行里面的initView()

    override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()

1.4.然后执行onCreate中的showFragment函数。

   showFragment(savedInstanceState.getInt(POSITION))
bottom_navigation!!.selectedItemId=savedInstanceState.getInt(SELECT_ITEM)

1.5.然后进入NewsTabLayout中的getInstance函数

  newsTabLayout = NewsTabLayout.getInstance()
ft.add(R.id.container, newsTabLayout, NewsTabLayout::class.java.name)

1.6.然后执行getInstance函数==>new NewsTabLayout()

public static NewsTabLayout getInstance(){
if(instance==null){
instance=new NewsTabLayout();
}
return instance;
}

1.7.然后执行NewsTabLayout中的onCreateView(它是一个Fragment)  

View view = inflater.inflate(R.layout.fragment_news_tab, container, false);
initView(view);
initData();
return view;

1.8.按顺序来==>initData()==>内部有一个initTabs()

   for(NewsChannelBean bean:channelList){
Fragment fragment=null;
String channelId=bean.getChannelId(); switch (channelId){
case "essay_joke":
if(map.containsKey(channelId)){
fragmentList.add(map.get(channelId));
}else{
fragment= JokeContentView.newInstance();
fragmentList.add(fragment);
}
break;

  这里就是加载了8个初始碎片。

1.9.然后执行NewsTabLayout中的initData()中的

   adapter=new BasePagerAdapter(getChildFragmentManager(),fragmentList,titleList);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(15);

1.10.进入RxBus==>注册了NewsTabLayout.TAG

 observable=RxBus.getInstance().register(NewsTabLayout.TAG);
observable.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean isRefresh) throws Exception {
if(isRefresh){
initTabs();
adapter.recreateItems(fragmentList,titleList);
}
}
});

1.11.回到NewsTabLayout的onCreateView。返回view。

 @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                            @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_news_tab, container, false);
initView(view);
initData();
return view;
}

1.12.然后执行Fragment的performCreateView()

1.13.然后执行RxAppCompatActivity==>onStart()

1.14.然后执行Activity==>convertToTranslucent()

1.15.执行半天后到NewsTabLayout的onResume()中

 @Override
public void onResume() {
super.onResume();
linearLayout.setBackgroundColor(SettingUtil.getInstance().getColor());
}

2.进入JokeContentView

2.1.首先监听到的是setPresenter

 @Override
public void setPresenter(IJokeContent.Presenter presenter) {
if (null == presenter) {
this.presenter = new JokeContentPresenter(this);
}
}

2.2. 执行GroupBean==>自定义的一个Bean类非常庞大。

 private List<JokeContentBean.DataBean.GroupBean> groupList=new ArrayList<>();

2.3.执行BaseFragment中的setPresenter函数

  @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setPresenter(presenter);
}

2.4.然后进入LazyLoadFragment的onCreate()

 @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

2.5.然后多次在JokeContentPresenter的构造函数中循环

2.6.然后进入BaseFragment的onCreateView中

 @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                            @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(attachLayoutId(), container, false);
initView(view);
initData();
return view;
}

2.7.然后执行BaseListFragment的attachLayoutId函数。

@Override
protected int attachLayoutId() {
return R.layout.fragment_list;
}

2.8.然后执行到JokeContentView的initView中

 @Override
protected void initView(View view) {
super.initView(view);
adapter = new MultiTypeAdapter(oldItems);
Register.registerJokeContentItem(adapter);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
if (canLoadMore) {
canLoadMore = false;
presenter.doLoadMoreData();
}
}
});
}

2.9.然后执行到Register中的registerJokeContentItem函数

 public static void registerJokeContentItem(@NonNull MultiTypeAdapter adapter) {
adapter.register(JokeContentBean.DataBean.GroupBean.class, new JokeContentViewBinder());
adapter.register(LoadingBean.class, new LoadingViewBinder());
adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
}

2.10.然后执行JokeContentViewBinder

2.11.然后回到JokeContentView的initView

  recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
if (canLoadMore) {
canLoadMore = false;
presenter.doLoadMoreData();
}
}
});

2.12.然后回到BaseFragment中的onCreateView函数

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(attachLayoutId(), container, false);
initView(view);
initData(); //=====执行到这里了
return view;
}

2.13.然后进入JokeContentView中的initData()

 @Override
protected void initData() { }

2.14.然后回到LazyLoadFragment中,执行onActivityCreate

 @Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isViewInitiated = true;
prepareFetchData();
}

2.15.执行prepareFetchData()

    public boolean prepareFetchData() {
return prepareFetchData(false);
} public boolean prepareFetchData(boolean forceUpdate) {
if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
fetchData();
isDataInitiated = true;
return true;
}
return false;
}

3.回到BaseFragment的onCreateView

3.1.回到BaseFragment的onCreateView

 @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                                @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(attachLayoutId(), container, false);
initView(view);
initData();
return view;
}

3.2.进入BaseListFragment中的attachLayoutId

@Override
protected int attachLayoutId() {
return R.layout.fragment_list;
}

3.3.进入JokeContentView中的initView函数

 @Override
protected void initView(View view) {
super.initView(view);
adapter = new MultiTypeAdapter(oldItems);
Register.registerJokeContentItem(adapter);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
if (canLoadMore) {
canLoadMore = false;
presenter.doLoadMoreData();
}
}
});
}

3.4.再次进入Register

public class Register {
public static void registerJokeContentItem(@NonNull MultiTypeAdapter adapter) {
adapter.register(JokeContentBean.DataBean.GroupBean.class, new JokeContentViewBinder());
adapter.register(LoadingBean.class, new LoadingViewBinder());
adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
}
}

3.5.回到BaseFragment的onCreateView函数

  执行initData。

  进入JokeContentView

 @Override
protected void initData() { }

3.6.再次进入LazyLoadFragment的onActivityCreated

 @Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isViewInitiated = true;
prepareFetchData();
}

3.7.回到BaseFragment的onCreateView 

 @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                                @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(attachLayoutId(), container, false);
initView(view);
initData();
return view;
}

3.8.进入BaseListFragment的attachLayoutId

  @Override
protected int attachLayoutId() {
return R.layout.fragment_list;
}

4.总结一下

4.1.首先加载底部导航栏的4个大碎片

  NewsTabLayout/PhotoTabLayout/VideoTabLayout/MediaChannelVideo

4.2.加载NewsTabLayout详细的布局==>fragment_news_tab。

  然后确定8个默认的fragment(全部都是news_tab中的)

4.3.NewsTabLayout在onCreateView中的initData初始化数据的时候,用上了RxBus+Observable

4.4.执行LazyLoadFragment的setUserVisibleHint的不可见。

4.5.继承关系的执行顺序为: 

父类静态代码区和父类静态成员
子类静态代码区和子类静态成员
父类非静态代码区和普通成员
父类构造函数
子类非静态代码区和普通成员
子类构造函数

4.6.BaseFragment应该算是比较祖先级别的。所以先执行这个函数的onCreate==>onCreateView

  在BaseFragment中已经有了一个泛型的 presenter了。

4.7.在子类中JokeContentView中有一个设置presenter的方法。设置成JokeContentPresenter。

  JokeContentPresenter实现了IJokeContent.Presenter接口。

  IJokeContent主要有两个内部接口View+Presenter。

4.8.在JokeContentPresenter中进行API请求,主要函数为doLoadData()。

  采用了一个RetrofitFactory缓存机制。

  

4.9.然后回到子类,也就是祖先的后代继承者。BaseListFragment

4.10.然后到LazyLoadFragment中的onActivityCreate中执行 准备取数据的操作。prepareFetchData()。

4.11.然后回到子类JokeContentView来加载数据了。onLoadData()

  首先执行BaseListFragment复写的onShowLoading函数。

  然后执行子类JokeContentPresenter来doLoadData()来请求数据。(调用方式为:presenter.doLoadData())

  这里进行了Cookie持久化操作。

4.12.然后回到懒加载LazyLoadFragment中,成功执行了prepareFetchData,设置初始化为true。

4.13.然后到祖先BaseFragment中的onCreateView函数中,加载fragment_list布局。

  执行祖先的initView==>成功转到JokeContentView的initView(Register注册了数据+recylerView监听滑动)

  然后转到BaseListFragment的initView(设置SwipeRefreshLayout的刷新事件)

  然后转到RetrofitFactory添加缓存

  然后转到JokeContentView的initView(继续Register+recyclerView监听滑动)

  这个Register里面关联了一个JokeContentViewBinder绑定,比较复杂。

  然后转到JokeContentPresenter的doLoadData来请求API

  然后到懒加载LazyLoadFragment的onActivityCreated中==>prepareFetchData()准备取数据

  然后回到祖先的onCreateView中加载fragment_list布局

  继续循环....

TouTiao开源项目 分析笔记7 加载数据的过程的更多相关文章

  1. TouTiao开源项目 分析笔记15 新闻详情之两种类型的实现

    1.预览效果 1.1.首先看一下需要实现的效果. 第一种,文字类型新闻. 第二种,图片类型新闻. 1.2.在NewsArticleTextViewBinder中设置了点击事件 RxView.click ...

  2. TouTiao开源项目 分析笔记18 视频详情页面

    1.效果预览 1.1.需要做到的真实效果 1.2.触发的点击事件 在MediaArticleVideoViewBinder的每一个item点击事件中: VideoContentActivity.lau ...

  3. TouTiao开源项目 分析笔记17 新闻媒体专栏

    1.效果预览 1.1.要实现的效果 1.2.如何调转到新闻媒体专栏 点击右上角的用户图标. 在新闻详情页面的Fragment的菜单点击事件中触发. case R.id.action_open_medi ...

  4. TouTiao开源项目 分析笔记16 新闻评论

    1.要达到的效果 1.1.主要效果图 点击了标题栏的消息图标后,然后会跳转到评论详情的页面. 1.2.触发的点击事件 在新闻详情的片段中的菜单点击事件中 设置上方标题栏的消息标的监听事件 case R ...

  5. TouTiao开源项目 分析笔记14 段子评论

    1.段子页面详情 1.1.先看看预览界面吧 左边的页面已经实现了,现在的目的就是要实现点击左侧的每一个item 然后跳转到右边相应的段子详情页面. 1.2.首先肯定有右侧这个活动==>JokeC ...

  6. TouTiao开源项目 分析笔记20 问答详情

    1.效果预览 1.1.效果预览,从问答列表开始 前面实现了从列表到内容. 这里主要讲解从内容到详情. 点击每一个回答内容,进入回答详情页面. 1.2.触发的点击事件 在WendaContentView ...

  7. TouTiao开源项目 分析笔记19 问答内容

    1.真实页面预览 1.1.成果预览 首先是问答列表 然后每个item设置点击事件,进入问答内容列表 然后每一个问答内容也设置点击事件,进入问答详情 1.2.触发事件. 在WendaArticleOne ...

  8. TouTiao开源项目 分析笔记8 图解分析数据加载方式

    1.整体构架 1.1.以一个段子页面为例,列出用到的主要的类,以图片的方式展示. 1.2.基础类 这里最基础的接口有:   IBaseView<T>==>定义了5个方法. 然后最基础 ...

  9. TouTiao开源项目 分析笔记6

    1.NewsChannelBean简单类笔记 1.1.Comparable接口的实现和使用 参考文章:Comparable接口的实现和使用. 因为NewsChannelBean实现了Comparabl ...

随机推荐

  1. android打包代码混淆

    android应用打包代码混淆:   1.将project.propertier文件中的proguard.config=proguard-android.txt打开  拷贝指定的文件到应用中 2.更改 ...

  2. EF--Model First

    Model First先设计Model对象,再由对象生成数据库. 1.新建控制台项目,名称ModelFirst,确定. 2.点击选中项目,右键-->添加-->新建项目--选择数据模板--& ...

  3. Cordova各个插件使用介绍系列(七)—$cordovaStatusbar手机状态栏显示

    在项目中发现Android和iOS在手机状态栏样式不一样,然后就查到有一个cordova插件可以解决这个问题 1.下载插件$cordovaStatusbar命令: cordova plugin add ...

  4. SQL中的聚合函数

    聚合函数是对一组值执行计算并返回单一的值的函数,它经常与SELECT语句的GROUP BY子句一同使用,SQL SERVER 中具体的聚合函数如下:1. AVG 返回指定组中的平均值,空值被忽略. 例 ...

  5. org.springframework.beans.factory.BeanNotOfRequiredTypeException

    写一个代码:关于Spring Bean的装配.基于annotation实现的范例代码. 出现了错误: 十一月 14, 2018 4:51:01 下午 org.springframework.conte ...

  6. ui.datepicker的回显问题

    应用场景: 页面上有一些现有的输入框,需要调用日期插件,同时还要clone一份,动态添加到页面中,动态生成的输入框在调用datepicker的时候,click事件有效,但是选择的时间无法回显到对应的输 ...

  7. SAP成都研究院Sunshine: 我的C4C实习感受和保研之路

    今天的文章来自SAP成都一位实习生,曾经和Jerry同在C4C成都开发团队一起工作过.在Sunshine最后一个工作日里,Jerry和Sunshine一起吃饭的时候,她曾经聊到接下来的保研打算和将来工 ...

  8. VScode中的golang代码规范太严格,怎么处理。

    在vscode的配置文件settings.json中,加入下面的配置,一般设置为0.8即可. "go.lintFlags": [ "-min_confidence=.8& ...

  9. Jenkins配置(Jenkins如何与maven项目进行连用)

    一同事,在问关于Jenkins搭建后,他是如何与我们项目进行连用的,如何通过Jenkins去编译我们的项目的,现在介绍下如何通过Jenkins持续编译我们的项目 配置过程 1.确定我们已经搭建好了Je ...

  10. 使用extentreports美化testng报告2,增加监听

    有兴趣研究了extentreports报告美化插件,但是因为发现插件有很多内容不能自定义,所以放弃了这个插件,我扩充了官方代码的demo,在testng中增加了监听,并打印了一些测试用例,现在我把两个 ...