Android ViewPager+Fragment生命周期优化

巧了我就是萌 提交于 2019-12-05 23:33:31
一.页面缓存

ViewPager默认会缓存1~2个页面,也就是当前页面的前一个页面和后一个页面,如果后一个页面不存在,则不在缓存,反之会被缓存

offscreenPageLimit的默认值为1

         int offscreenPageLimit =  mViewPager.getOffscreenPageLimit();
         Log.e("MainActivity", "offscreenPageLimit="+offscreenPageLimit);

1.1轮播图

有时,需要使用ViewPager+反射匀速Scroller+ImageView做轮播图时,轮播的图片超过4个就会出现空白的问题,对于这种问题,明细我们需要把offscreenPageLimit设置为n-1,(n为图片的个数),这样把图片缓存起来(轮播图一般在首页,长期存在,因此也就不要想着及时释放掉这几张图片了)

mViewPager.setOffscreenPageLimit(imageList.size()-1);
二. 当前视图Fragment更新

ViewPager+Fragment也会受到offscreenPageLimit的影响,对于这个,建议使用n-1模式

   List<BaseFragment> fragmentList = Collections.synchronizedList(new ArrayList<BaseFragment>());
         fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(0)));
         fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(1)));
         fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(2)));
         mViewPager.setAdapter(new ViewPagerFragmentAdapter(getSupportFragmentManager()));
         //CommonFragment是BaseFragment的子类
         mViewPager.setOffscreenPageLimit(fragmentList.size()-1);
         mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
        	 @Override
        	public void onPageSelected(int position) {
        		super.onPageSelected(position);
        		BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(position);
        		fragment.updateFragment();
        	 }
         });

当然问题来了,如何每次更新呢,对于这个问题,我们的解决方案是在BaseFragment中添加如下2个方法以及变量isFirst 

private boolean isFirst = true;

public void updateFragment()
{
	if(isFirst)
	{
		isFirst = false;
		List<Fragment> fragments = getFragmentManager().getFragments();
		if(fragments.indexOf(this)!=0) //如果是第一个页面,第一次调用
		{
				return;
		}
	}
	if(getView()==null)
	{
		View decorView = null;
		if(getActivity()!=null)
		{
			decorView = getActivity().getWindow().getDecorView();
		}
		if(decorView!=null)
		{
		   decorView.postDelayed(new Runnable() {
			@Override
			public void run() {
				updateFragment();
				}
				}, 100);
			}
		}else{
			onRestart();
		}
	}
	
	protected void onRestart()
	{
		
	}

这样我们在BaseFragment的子类中重写onRestart()即可,onRestart在第一次不会调用,这样就避免了onCreate和onRestart()同时调用一个接口

三.FragmentPagerAdapter与FragmentStatePagerAdapter性能优化

如上是一张Fragment生命周期图,其实不是很完整在 onCreateView---->onStart之间应该是

onCreateView->onViewCreated->onActivityCreated->onViewStateRestored->onStart

按照我们Fragment的优化方案,应该分2类优化


第一类优化(重点改善页面少,内存,性能要求高的需求)

当我们使用FragmentTabHost,FragmentPagerAdapter,FragmentTransaction中非replace操作的时候,我们的优化需要参考

Android Fragment的生命周期和Inflate优化


第二类优化(重点改善页面多,内存,性能要求高的需求)

当我们使用的是FragmentStatePagerAdapter或者,FragmentTransaction中的replace操作,我们需要注意,在生命周期中的

onSaveInstance<------>onViewStateRestored

2个方法,解决我们开发中,对于页面不确定或者页面较多的问题,类似Activity中的onSaveInstance和onRestoreInstance的用法,通过这种方法,来提高我们的效率。


四.setUserVisibleHint空指针问题的解决
android.support.v4.app.Fragment.setUserVisibleHint null pointer on app resuming
android.support.v4.app.Fragment.setUserVisibleHint in Fragment.java on Line 819
android.support.v4.app.FragmentPagerAdapter.setPrimaryItem in FragmentPagerAdapter.java on Line 130

对于如上问题,我们需要FragmentStatePagerAdapter替换FragmentPagerAdapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!