转载于:

作者:尹star
链接:http://www.jianshu.com/p/c5d29a0c3f4c
來源:简书
 
ViewPager+Fragment的模式再常见不过了,以国民应用微信为例,假设微信也是ViewPager+Fragment的实现方式,那表现形式上就是一个ViewPager管理了四个Fragment,左右滑动来回切换。但是ViewPager有一个奇葩的特性叫:预加载,比如打开微信,首先看到的是第一个Tab(微信),但事实上第二个Tab(通讯录)已经加载好了。当选择第二个Tab(通讯录),第三个Tab(发现)已经加载好了,以此类推。
但上诉ViewPager+Fragment的这种组合并不完美,因为我希望用户选择了哪个Tab再去加载哪个Tab的数据,而不要去做预加载,假如当前页面和预加载页面都有大量的网络请求,可能就会比较慢,有很多请求在排队。关于这个问题,也有很偏激的做法,比如弃用ViewPager,自己手动管理Fragment,或者直接禁掉ViewPager预加载。有一种比较合适的方案是保持ViewPager预加载的特性,但是只初始化View,选择当前Tab的时候再进行网络请求。关于这一方案的实现,也是众说纷纭,千奇百怪。
直接上代码。
public abstract class BasePageFragment extends Fragment {

    protected boolean isViewInitiated;
protected boolean isVisibleToUser;
protected boolean isDataInitiated; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isViewInitiated = true;
prepareFetchData();
} @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
this.isVisibleToUser = isVisibleToUser;
prepareFetchData();
} public abstract void fetchData(); public boolean prepareFetchData() {
return prepareFetchData(false);
} public boolean prepareFetchData(boolean forceUpdate) {
if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
fetchData();
isDataInitiated = true;
return true;
}
return false;
} }
这是一个父类,看代码这里只有一个setUserVisibleHint需要说下,这是一个相当生僻的方法,我们可以用这个方法来判断当前UI是否可见,所以在prepareFetchData方法里我们做如下判断:就是当前UI可见,并且fragment已经初始化完毕,如果网络数据未加载,那么请求数据,或者需要强制刷新页面,那么也去请求数据,So easy。子Fragment只需要继承父类,实现抽象方法,在fetchData()里做网络请求或者其他耗时操作即可。再在写个子类吧。
public class PageFragment extends BasePageFragment {

    public static PageFragment newInstance(String title){
PageFragment fragment = new PageFragment();
Bundle args = new Bundle();
args.putString("key_fragment_title", title);
fragment.setArguments(args);
return fragment;
} private String title;
private TextView tv; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
title = getArguments().getString("key_fragment_title");
Trace.d(title + ":onCreate");
} @Override
public void onResume() {
super.onResume();
Trace.d(title + ":onResume");
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Trace.d(title + ":onCreateView");
tv = new TextView(getActivity());
return tv;
} @Override
public void fetchData() {
tv.setText(title);
/** * 在这里请求网络。 */
} }

如果你也有这样的需求或者烦恼,保证药到病除。

有同学说实践过程中遇到了些问题,比如Fragment只刷新一次,这个问题只要手动调用prepareFetchData(),传true即可强制刷新了。还有同学质疑setUserVisibleHint()和onActivityCreated()的执行先后的问题。关于这个请看下图。

最新文章

  1. 1Z0-053 争议题目解析486
  2. https协议了解,以及相关协议的解析
  3. Winform TreeView 节点拖动
  4. autohotkey-【GUI】Switch between Windows of the Same Application
  5. rnn lstm
  6. 解决 kindle 书籍字体颜色偏淡问题的方法
  7. wildcard 处理全部文件
  8. java开发软件的安装
  9. cocos2D(九)---- CCAction
  10. 重写javascript浮点运算
  11. 使用Spring MVC测试Spring Security Oauth2 API
  12. SQL Server使用sp_spaceused查看表记录存在不准确的情况
  13. Oracle基础--创建临时表空间/表空间/创建用户/授权
  14. centos安装pg以及pg配置ssl
  15. python中的hasattr()、getattr()、setattr()
  16. Scala泛型[T]的使用
  17. Ubuntu Eclipse ns3编译中 遇到的OSError 系列问题
  18. 十七、S3C2440 音频解码芯片WM8976声卡驱动移植、madplay测试
  19. ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer::ComputeF21 (OpenCV 细节)
  20. java HttpClient 获取页面Cookie信息

热门文章

  1. MeasureString 通过文本宽度获取绘制高度
  2. Linux nc 命令传输文件
  3. Ext3和Ext4文件系统区别
  4. SSD中的GC机制以及Trim
  5. Shiro 加密helloWorld
  6. 下一个计划 : .NET/.NET Core应用性能管理系统
  7. 如何访问 Service?- 每天5分钟玩转 Docker 容器技术(99)
  8. MapReduce 入门之一步步自实现词频统计功能
  9. 用Vim 加密文本
  10. continue,break以及加上标签的使用(goto思路)