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

转载 2016年06月02日 09:12:48

在项目中,都或多或少地使用的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() {

			@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 mFragments = new ArrayList();
	
	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;
		}
	}
}

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

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方。例如你在ViewPager中添加了三个Fragment,当加载V...

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

用过ViewPage+Fragment组合的童鞋自然知道这个问题,没有遇到的同学祝愿你们永远不会遇到,呵呵。 在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fra...

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

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方。例如你在ViewPager中添加了三个Fragment,当加载V...
  • hyq912
  • hyq912
  • 2015年01月12日 16:45
  • 12643

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

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方。例如你在ViewPager中添加了三个Fragment,当加载V...

Fragment延迟加载技术(解决Viewpager预加载fragment)

看到很多朋友问到,如何解决ViewPager预加载fragment的问题,一些因ViewPager预加载fragment而出现的bug。所以今天就写了这篇博客。   缘由:ViewPager结合fra...

ViewPager+Fragment滑动界面,并做延迟加载【终极解决】

我们在做应用的过程中,ViewPager+Fragment是很常见的,但是如果在每次应用启动的时候就去加载大量的网络数据肯定是不好的,我们往往需要的是只加载布局暂时不加载数据,事先把布局加载好,滑动的...

ViewPager+Fragment滑动界面,并做延迟加载

Activity继承FragmentActivity package com.bitcare.activity; import java.util.ArrayList; import java.ut...

ViewPager+Fragment延迟加载

viewPager+Fragment延迟加载的例子

Android中ViewPager+Fragment懒加载问题解决方案Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案在Android中我们经常会用到ViewPager+Fragment组合。然而,有一个很让人头疼的问...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ViewPager+Fragment取消预加载(延迟加载)
举报原因:
原因补充:

(最多只允许输入30个字)