Fragment和viewPager拒绝预加载
来源:互联网 发布:微控加群软件 编辑:程序博客网 时间:2024/06/07 03:34
八月十五号更新:
再次修改BaseFragment
public abstract class BaseFragment extends Fragment { protected boolean isLoad; protected boolean isPrepared; protected boolean isVisible; protected static final String FRAGMENT_INDEX = "fragment_index"; protected int index = 0; protected int page = 1; protected boolean isNull = false; protected View view; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (view == null) { view = initView(savedInstanceState); isPrepared = true; } initById(); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initData(); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (getUserVisibleHint()) { isVisible = true; onVisible(); } else { isVisible = false; } } <T extends View> T getView(int id) { //noinspection unchecked return (T) view.findViewById(id); } private void onVisible() { initData(); } protected abstract View initView(Bundle savedInstanceState); protected abstract void initById(); protected abstract void initData(); protected void setLoad() { isLoad = true; }}
继承这个BaseFragment 因为setUserVisibleHint这个方法只有碰到ViewPager才会触发,所以所有的fragment都可以继承
继承Fragment
public class TestFragment extends BaseFragment { @Override protected View initView(Bundle savedInstanceState) { return null; } @Override protected void initById() { } @Override protected void initData() { if (!isPrepared || !isVisible || isLoad) { return; }<span style="white-space:pre"></span>//填充数据 setLoad(); }}
在项目中使用Fragment和viewPager是很常见的事情,但是细心的人就会发现如果fragment有多个页面的话,当你还没切换到第二个页面的时候viewpager就已经把第二个页面在后台加载了,这个是viewpager的特性。
举个简单的例子:你在页面加个progressBar,让他显示一秒再消失,但是你打开App,然后等两秒,再切换到第二个页面,这个时候就会发现progressbar早已经消失了。
阅读viewpager的源码就会发现有这个方法setOf'fscreenPageLimit();
这个就是控制viewpager一次加载几个页面的方法,看原源码就会发现就算你传0,viewpager也会默认为1,通过修改viewpager可以实现不预加载,但是以后SDK更新的话你就用不到新东西,这个方法明显是不理想的.
public void setOffscreenPageLimit(int limit) { if (limit < DEFAULT_OFFSCREEN_PAGES) { Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + DEFAULT_OFFSCREEN_PAGES); limit = DEFAULT_OFFSCREEN_PAGES; } if (limit != mOffscreenPageLimit) { mOffscreenPageLimit = limit; populate(); } }DFEAULT_OFFSCREEN_RAGES这个变量是1
再来看看Fragment的API,setUserVisibleHint这个方法告诉我们Fragment的UI是否是可见的。
很明显从这里下手可以得到想要的结果。
Demo采用了TabLayout和viewpager结合滑动效果
这里在絮叨一下TabLayout,tabMode有两个属性,一个是fixed,另一个是scrollable,前者是不管有几个tab,只占一个屏幕的宽度,后者自适应屏幕的宽度,滑动显示tab
现在想要的结果是切换哪个页面再加载哪个页面的数据为了效果明显加一个进度显示,这样很直观就可以看出来
这个是主页面的xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="demo.fragmentdemo.MainActivity"> <android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:tabMode="scrollable" app:tabSelectedTextColor="@color/colorAccent" /> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
viewpager页面的xml
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="30sp" /> <ProgressBar android:id="@+id/progressBar" android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:visibility="gone" /></FrameLayout>
package demo.fragmentdemo;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;/** * by 12406 on 2016/5/12. */public abstract class BaseFragment extends Fragment { boolean isVisible; static final String FRAGMENT_INDEX = "fragment_index"; int index = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = getArguments(); if (bundle != null) { index = bundle.getInt(FRAGMENT_INDEX); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = initView(); initData(); return view; } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (getUserVisibleHint()) { isVisible = true; onVisible(); } else { isVisible = false; onInvisible(); } } private void onVisible() { initData(); } private void onInvisible() { } protected abstract View initView(); protected abstract void initData();}在可见的时候调用onVisible();不可见的时候去调用onInvisible();
继承BaseFragment的Fragment
package demo.fragmentdemo;import android.os.Bundle;import android.os.Handler;import android.support.v4.app.Fragment;import android.view.View;import android.widget.ProgressBar;import android.widget.TextView;/** * by 12406 on 2016/5/12. */public class DemoFragment extends BaseFragment { private View inflate; private TextView tv; private boolean isPrepared;//初始化完成 private boolean isLoad;//是否加载过 private ProgressBar progressBar; public static Fragment newInstance(int index) { Bundle bundle = new Bundle(); DemoFragment fragment = new DemoFragment(); bundle.putInt(FRAGMENT_INDEX, index); fragment.setArguments(bundle); return fragment; } @Override protected View initView() { if (inflate == null) { inflate = View.inflate(getActivity(), R.layout.fragment_viewpager, null); tv = (TextView) inflate.findViewById(R.id.tv); progressBar = (ProgressBar) inflate.findViewById(R.id.progressBar); isPrepared = true; } return inflate; } @Override protected void initData() { if (!isPrepared || !isVisible || isLoad) { return; } progressBar(); isLoad = true; } public void switchId(int id) { switch (id) { case 0: tv.setText("界面一"); break; case 1: tv.setText("界面二"); break; case 2: tv.setText("界面三"); break; case 3: tv.setText("界面四"); break; case 4: tv.setText("界面五"); break; case 5: tv.setText("界面六"); break; case 6: tv.setText("界面七"); break; } } public void progressBar() { progressBar.setVisibility(View.VISIBLE); new Handler().postDelayed(new Runnable() { @Override public void run() { progressBar.setVisibility(View.GONE); switchId(index); } }, 1000); }}
用一个进度条很明显就可以看出来是否预加载了。
下载链接:Demo
- Fragment和viewPager拒绝预加载
- viewpager fragment 预加载
- ViewPager+Fragment组合的预加载和懒加载
- ViewPager+Fragment组合的预加载和懒加载
- ViewPager+Fragment 组合的预加载和懒加载
- ViewPager+Fragment组合的预加载和懒加载
- viewPager+fragment阻止预加载
- ViewPager + Fragment 预加载问题
- ViewPager+Fragment 预加载问题
- Fragment+Viewpager防止预加载
- ViewPager+Fragment取消预加载
- ViewPager+Fragment预加载解决方案
- viewpager+fragment 重写viewpager取消预加载
- Fragment+ViewPager 不预加载下一个Fragment
- viewpager和fragment实现预加载和fragment的单一加载
- viewPager+Fragment的生命周期和预加载问题
- viewpager+fragment防止销毁和预加载问题
- Fragment嵌套Fragment,Viewpager和Fragment联动,懒加载
- 关于java I/O的杂谈
- 斗地主手牌最少手数的搜索
- R语言文本分析(4)
- sar
- android开发环境的搭建
- Fragment和viewPager拒绝预加载
- 最短路径
- 高级IO-fcntl记录锁
- 赵志勇记录下的算法+程序
- 优质资源分享
- iOS开发封装带有Button的UIView控件,使用代理给button添加点击事件
- Retrofit--使用Retrofit时怎样去设置OKHttp
- HDU3397 Sequence operation(线段树的区间合并)
- STL之set和multiset详解