Fragment和viewPager拒绝预加载

八月十五号更新:

再次修改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>


创建一个BaseFragment

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


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值