ViewPager+Fragment LazyLoad最优解
来源:互联网 发布:美工设计职责 编辑:程序博客网 时间:2024/06/01 20:24
(转载)http://www.jianshu.com/p/c5d29a0c3f4c
ViewPager+Fragment LazyLoad最优解
ViewPager+Fragment的模式再常见不过了,以国民应用微信为例,假设微信也是ViewPager+Fragment的实现方式,那表现形式上就是一个ViewPager管理了四个Fragment,左右滑动来回切换。但是ViewPager有一个奇葩的特性叫:预加载,比如打开微信,首先看到的是第一个Tab(微信),但事实上第二个Tab(通讯录)已经加载好了。当选择第二个Tab(通讯录),第三个Tab(发现)已经加载好了,以此类推。
但上诉ViewPager+Fragment的这种组合并不完美,因为我希望用户选择了哪个Tab再去加载哪个Tab的数据,而不要去做预加载,假如当前页面和预加载页面都有大量的网络请求,可能就会比较慢,有很多请求在排队。关于这个问题,也有很偏激的做法,比如弃用ViewPager,自己手动管理Fragment,或者直接禁掉ViewPager预加载。有一种比较合适的方案是保持ViewPager预加载的特性,但是只初始化View,选择当前Tab的时候再进行网络请求。关于这一方案的实现,也是众说纷纭,千奇百怪。最后,还是选择男神Stay的方案。
直接上代码。
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()的执行先后的问题。关于这个请看下图。
- ViewPager+Fragment LazyLoad最优解
- ViewPager+Fragment LazyLoad 最优解
- ViewPager+Fragment LazyLoad懒加载最优解
- ViewPager+Fragment LazyLoad 最优解决方案
- Android Fragment + ViewPager +LazyLoad的应用
- ViewPager+Fragment最优实现方案
- baseadapter getview 重复刷新 ViewPager -- Fragment 切换卡顿 LazyLoad
- Fragment+ViewPager
- Viewpager&Fragment
- viewpager + fragment
- viewpager+fragment
- viewpager+fragment
- ViewPager+Fragment
- viewPager+fragment
- ViewPager+Fragment
- ViewPager+Fragment
- viewpager+fragment
- Fragment+ViewPager
- 安卓时间工具类,计算时间差,比较当前时间
- docker背后的namespaces
- 移动网络简介与RRC
- 数据库原理(上)--收集得空看
- Android Studio 2.1.1 中使用直接JNI与间接编译JNI
- ViewPager+Fragment LazyLoad最优解
- iOS Animation各种动画效果
- [DBunit] 1,DBunit简单入门
- Docker 入门教程(八)
- 本地如何搭建IPv6环境测试你的APP
- 430_AD采样不准确问题
- poj 1330 Nearest Common Ancestors lca rmq在线算法
- qt4连接mysql(2)
- 宏与内联