• ViewPager+Fragment取消预加载(延迟加载)


    在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方。例如你在ViewPager中添加了三个Fragment,当加载ViewPager中第一个Fragment时,它会默认帮你预先加载了第二个Fragment,当你加载第二个Fragment时,它会帮你加载第三个Fragment。这样虽然有时很好,但是用户只需看一个Fragment时,我们就做了一些多余工作加载了第二个Fragment。在这只需要取消Fragment的预加载即可,只有当用户切换到某个Fragment才加载..

    首先,介绍两个方法void setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint(),它们分别用作设置/获得Fragment可见状态,我们可以重写Fragment在其中做判断,代码如下:

    import android.support.v4.app.Fragment;
     
    public abstract class BaseFragment extends Fragment {
         
        /** Fragment当前状态是否可见 */
        protected boolean isVisible;
         
         
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
             
            if(getUserVisibleHint()) {
                isVisible = true;
                onVisible();
            } else {
                isVisible = false;
                onInvisible();
            }
        }
         
         
        /**
         * 可见
         */
        protected void onVisible() {
            lazyLoad();     
        }
         
         
        /**
         * 不可见
         */
        protected void onInvisible() {
             
             
        }
         
         
        /** 
         * 延迟加载
         * 子类必须重写此方法
         */
        protected abstract void lazyLoad();
    }

    在我们的Fragment中,只需要继承这个类,然后重写其中的lazyLoad()方法,当Fragment对用户可见(即用户切换到此Fragment时)我们在lazyLoad()中加载所需数据,详细代码看下面,我写了个假的获取数据线程:

    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
     
    public class CustomListFragment extends BaseFragment {
     
        private static final String FRAGMENT_INDEX = fragment_index;
        private final int FIRST_FRAGMENT = 0;
        private final int SECOND_FRAGMENT = 1;
        private final int THIRD_FRAGMENT = 2;
     
        private TextView mFragmentView;
     
        private int mCurIndex = -1;
        /** 标志位,标志已经初始化完成 */
        private boolean isPrepared;
        /** 是否已被加载过一次,第二次就不再去请求数据了 */
        private boolean mHasLoadedOnce;
     
        /**
         * 创建新实例
         * 
         * @param index
         * @return
         */
        public static CustomListFragment newInstance(int index) {
            Bundle bundle = new Bundle();
            bundle.putInt(FRAGMENT_INDEX, index);
            CustomListFragment fragment = new CustomListFragment();
            fragment.setArguments(bundle);
            return fragment;
        }
     
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            if(mFragmentView == null) {
                mFragmentView = (TextView) inflater.inflate(R.layout.fragment, container, false);
                //获得索引值
                Bundle bundle = getArguments();
                if (bundle != null) {
                    mCurIndex = bundle.getInt(FRAGMENT_INDEX);
                }
                isPrepared = true;
                lazyLoad();
            }
             
            //因为共用一个Fragment视图,所以当前这个视图已被加载到Activity中,必须先清除后再加入Activity
            ViewGroup parent = (ViewGroup)mFragmentView.getParent();
            if(parent != null) {
                parent.removeView(mFragmentView);
            }
            return mFragmentView;
        }
     
        @Override
        protected void lazyLoad() {
            if (!isPrepared || !isVisible || mHasLoadedOnce) {
                return;
            }
     
            new AsyncTask<void, boolean="">() {
     
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    //显示加载进度对话框
                    UIHelper.showDialogForLoading(getActivity(), 正在加载..., true);
                }
     
                @Override
                protected Boolean doInBackground(Void... params) {
                    try {
                        Thread.sleep(2000);
                        //在这里添加调用接口获取数据的代码
                        //doSomething()
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return true;
                }
     
                @Override
                protected void onPostExecute(Boolean isSuccess) {
                    if (isSuccess) {
                        // 加载成功
                        setView();
                        mHasLoadedOnce = true;
                    } else {
                        // 加载失败
                    }
                    //关闭对话框
                    UIHelper.hideDialogForLoading();
                }
            }.execute();
        }
     
        private void setView() {
            // 根据索引加载不同视图
            switch (mCurIndex) {
            case FIRST_FRAGMENT:
                mFragmentView.setText(第一个);
                break;
     
            case SECOND_FRAGMENT:
                mFragmentView.setText(第二个);
                break;
     
            case THIRD_FRAGMENT:
                mFragmentView.setText(第三个);
                break;
            }
        }
    }

    到这里我们只是写好了Fragment,在FragmentActivity中还需要对ViewPager设置一下,让它每次只加载一个Fragment,ViewPager.setOffscreenPageLimit(int limit),其中参数可以设为0或者1,参数小于1时,会默认用1来作为参数,未设置之前,ViewPager会默认加载两个Fragment。所以,我们只需要调用下它,设置下加载Fragment个数即可。

    import java.util.ArrayList;
    import java.util.List;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.RadioButton;
    import android.os.Bundle;
     
    public class MainActivity extends FragmentActivity implements OnClickListener{
     
        private RadioButton mFstBtn;
        private RadioButton mSndBtn;
        private RadioButton mThdBtn;
         
        private ViewPager mViewPager;
        private ListFragmentPagerAdapter mPagerAdapter;
        private List<fragment> mFragments = new ArrayList<fragment>();
         
        private final int FIRST_FRAGMENT = 0;
        private final int SECOND_FRAGMENT = 1;
        private final int THIRD_FRAGMENT = 2;
         
         
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initButton();
            initViewPager();
        }
         
         
        /**
         * 初始化按钮
         */
        private void initButton() {
            mFstBtn = (RadioButton)findViewById(R.id.id_rb_fst);
            mFstBtn.setOnClickListener(this);
            mSndBtn = (RadioButton)findViewById(R.id.id_rb_snd);
            mSndBtn.setOnClickListener(this);
            mThdBtn = (RadioButton)findViewById(R.id.id_rb_thd);
            mThdBtn.setOnClickListener(this);
        }
         
         
        /**
         * 初始化ViewPager控件
         */
        private void initViewPager() {
            mViewPager = (ViewPager)findViewById(R.id.id_vp_viewpager);
            //关闭预加载,默认一次只加载一个Fragment
            mViewPager.setOffscreenPageLimit(1);
            //添加Fragment
            mFragments.add(CustomListFragment.newInstance(FIRST_FRAGMENT));
            mFragments.add(CustomListFragment.newInstance(SECOND_FRAGMENT));
            mFragments.add(CustomListFragment.newInstance(THIRD_FRAGMENT));
            //适配器
            mPagerAdapter = new ListFragmentPagerAdapter(getSupportFragmentManager(), mFragments);
            mViewPager.setAdapter(mPagerAdapter);
            mViewPager.setOnPageChangeListener(onPageChangeListener);
        }
     
         
        private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
             
            @Override
            public void onPageSelected(int position) {
                //根据用户选中的按钮修改按钮样式
                switch (position) {
                case FIRST_FRAGMENT:
                    mFstBtn.setChecked(true);
                    mSndBtn.setChecked(false);
                    mThdBtn.setChecked(false);
                    break;
     
                case SECOND_FRAGMENT:
                    mFstBtn.setChecked(false);
                    mSndBtn.setChecked(true);
                    mThdBtn.setChecked(false);
                    break;
                     
                case THIRD_FRAGMENT:
                    mFstBtn.setChecked(false);
                    mSndBtn.setChecked(false);
                    mThdBtn.setChecked(true);
                break;
                }
            }
             
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {}
             
            @Override
            public void onPageScrollStateChanged(int arg0) {}
        };
         
         
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.id_rb_fst:
                mViewPager.setCurrentItem(FIRST_FRAGMENT);
                break;
     
            case R.id.id_rb_snd:
                mViewPager.setCurrentItem(SECOND_FRAGMENT);
                break;
                 
            case R.id.id_rb_thd:
                mViewPager.setCurrentItem(THIRD_FRAGMENT);
                break;
            }
        }
    }
  • 相关阅读:
    Hibernate学习笔记1.2(Annotation版本的Helloworld)
    Hibernate学习笔记1.1(简单插入数据)
    Java 分页与原理(上)
    触发器实例讲解
    URLRewrite 实现方法详解
    一个数组:1,1,2,3,5,8,13,21...+m,求第30位数是多少?用递归实现;(常考!!!)
    面向对象
    ajax 判断账户密码 调取数据模糊查询 时钟
    asp.net 类,接口
    asp.net get图
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/5383072.html
Copyright © 2020-2023  润新知