今天正好有时间,研究下哪里出的问题,发现原来是viewpager的问题,viewpager有预加载的功能,如果不明白的可以看我之前发过的一篇博文,
连接http://blog.youkuaiyun.com/sinat_29874521/article/details/52869253
好了,言归正传,感谢http://www.cnblogs.com/wangfeng520/p/5807465.html提供的帮助,里边说的很详细,用的方法也很好
源码
/**
* Set a hint to the system about whether this fragment's UI is currently visible
* to the user. This hint defaults to true and is persistent across fragment instance
* state save and restore.
*
* <p>An app may set this to false to indicate that the fragment's UI is
* scrolled out of visibility or is otherwise not directly visible to the user.
* This may be used by the system to prioritize operations such as fragment lifecycle updates
* or loader ordering behavior.</p>
*
* @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
* false if it is not.
*/
public void setUserVisibleHint(boolean isVisibleToUser) {
if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
mFragmentManager.performPendingDeferredStart(this);
}
mUserVisibleHint = isVisibleToUser;
mDeferStart = !isVisibleToUser;
}
需要注意的是这个方法会在Fragment的onCreate()方法调用之前就调用 /**
* @return The current value of the user-visible hint on this fragment.
* @see #setUserVisibleHint(boolean)
*/
public boolean getUserVisibleHint() {
return mUserVisibleHint;
}
原谅我英语不好,我就不翻译了,说白了就是一句话
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
}
这里isVisibleToUser,就是判断该fragment是否是用户可见的视图,如果是则为true,不是则是false。而getUserVisibieHint()则是用来获取状态信息的,可见是true,不可见是false
用法当然更简单了
当然,还需要看一个方法的源码
/**
* Return true if the fragment is currently visible to the user. This means
* it: (1) has been added, (2) has its view attached to the window, and
* (3) is not hidden.
*/
final public boolean isVisible() {
return isAdded() && !isHidden() && mView != null
&& mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE;
}
用来做判断的,很容易理解,isVisible()方法可以判断Fragment的视图是否创建好,对于第一个显示的Fragment,因为isVisibleToUSer是true,但是isVisible()是false,那么在显示第一个Fragment的时候是空白的。但是对于其它的Fragment,因为存在ViewPager的预加载,当显示到Fragment的时候,isVisible()是true,而不是false。所以会在这个方法里面进行加载数据的操作
好了说下用法
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser && isVisible()){
setDatas();//获取数据
}
}
双重判断,省的做其他逻辑处理 @Override
public void onResume() {
super.onResume();
if(getUserVisibleHint()){
isFresh = true;
setDatas();
}
}因为我的获取数据的方法是刷新和加载全部卸载一起了所以isFresh = true可以忽略,之所以我这么写,不会重复加载数据,是因为我在获取初始化数据的时候,清空了数据集合,当然,这么做处于用户考虑,肯定不合理,毕竟费流量啊,不过其他的不考虑了,后续修改
PS:为何setUserVisibleHint()明明在onCreate()之前执行,但是还可以在里边写获取加载数据的方法呢?原因很简单,就是因为viewpager有预加载的功能,所以在进入这个fragment之前,viewpager就把这个fragment的控件加载完成了,而因为这个fragment是不可见的,所以isVisible()方法就是false,而不会运行加载数据的方法,但是说明一下,setUserVisibleHint()不是随着fragment的生命周期运行的,而是需要手动调用的,自己运行一下debug就明白了,回归正题,因为viewpager已经加载完成了所有控件,所以在运行到该fragment,该fragment可见,那么运行setUserVisibleHint(),而此时控件已经被viewpager预加载完成,isVisible()则是true,所以就可以吧加载数据的方法下载里边了。
反正我是这么理解的,如果有不对的地方请指出来,谢谢!
本文深入探讨了在使用ViewPager嵌套Fragment时遇到的预加载问题,通过分析源码揭示了问题根源,并提供了一种有效解决方案。
2776

被折叠的 条评论
为什么被折叠?



