ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter
Posted android_xiaogang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter相关的知识,希望对你有一定的参考价值。
在开发中ViewPager+fragment,包括缓存pager或者fragment中一些问题,什么时候该缓存销毁page,什么时候缓存销毁fragment问题
FragmentPagerAdapter,FragmentStatePagerAdapter的区别和适用场景
FragmentPagerAdapter
1、通过offscreenPageLimit来控制page container的cache数量 n*2+1;
2、当加载的page超出cache count会用FragmentManager来释放fragment
3、被释放的fragment实际上不会被完全回收,因为没有调用onDestory(),当再次回到这个page时也没有调用onCreate();
4、当fragment被显示在屏幕上时,setUserVisibleHint为true,不显示时为false.
适用于:
page是固定的,并且数量比较少,因为fragment不会被完全回收
FragmentStatePagerAdapter
其他三点都一样,不同的是
被释放的fragment会被完全回收,调用了onDestory()的方法;
适用于:
比较多的fragment,保证回收,清理内存
1、首先明确Fragment的生命周期
如果用ViewPager+fragment,首先应该明确fragment的生命周期,这个fragment什么时候开始创建,什么时候创建完成,什么时候创建view,什么时候可以加载数据。
几个重要容易模糊的生命周期
1、onAttach() 当一个fragment第一次绑定到它所属的activity中
/**
* Called when a fragment is first attached to its activity.
* @link #onCreate(Bundle) will be called after this.
* <p>Deprecated. See @link #onAttach(Context).
*/
@Deprecated
public void onAttach(Activity activity)
mCalled = true;
2、onCreate()它所属的activity正在创建中,并没有创建完成
/**
* Called to do initial creation of a fragment. This is called after
* @link #onAttach(Activity) and before
* @link #onCreateView(LayoutInflater, ViewGroup, Bundle).
*
* <p>Note that this can be called while the fragment's activity is
* still in the process of being created. As such, you can not rely
* on things like the activity's content view hierarchy being initialized
* at this point. If you want to do work once the activity itself is
* created, see @link #onActivityCreated(Bundle).
*
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
public void onCreate(@Nullable Bundle savedInstanceState)
mCalled = true;
3、onCreateView():可以把fragment的布局填充到view中,返回fragment的UI布局。
/**
* Called to have the fragment instantiate its user interface view.
* This is optional, and non-graphical fragments can return null (which
* is the default implementation). This will be called between
* @link #onCreate(Bundle) and @link #onActivityCreated(Bundle).
*
* <p>If you return a View from here, you will later be called in
* @link #onDestroyView when the view is being released.
*
* @param inflater The LayoutInflater object that can be used to inflate
* any views in the fragment,
* @param container If non-null, this is the parent view that the fragment's
* UI should be attached to. The fragment should not add the view itself,
* but this can be used to generate the LayoutParams of the view.
* @param savedInstanceState If non-null, this fragment is being re-constructed
* from a previous saved state as given here.
*
* @return Return the View for the fragment's UI, or null.
*/
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
return null;
4、onActivityCreated():这时候activity创建完成,并且fragment布局已经填充进去。
/**
* Called when the fragment's activity has been created and this
* fragment's view hierarchy instantiated. It can be used to do final
* initialization once these pieces are in place, such as retrieving
* views or restoring state. It is also useful for fragments that use
* @link #setRetainInstance(boolean) to retain their instance,
* as this callback tells the fragment when it is fully associated with
* the new activity instance. This is called after @link #onCreateView
* and before @link #onViewStateRestored(Bundle).
*
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
public void onActivityCreated(@Nullable Bundle savedInstanceState)
mCalled = true;
5、onDestroyView:销毁当前的view也就是填充的布局
/**
* Called when the view previously created by @link #onCreateView has
* been detached from the fragment. The next time the fragment needs
* to be displayed, a new view will be created. This is called
* after @link #onStop() and before @link #onDestroy(). It is called
* <em>regardless</em> of whether @link #onCreateView returned a
* non-null view. Internally it is called after the view's state has
* been saved but before it has been removed from its parent.
*/
public void onDestroyView()
mCalled = true;
6、onDestroy():销毁当前的fragment
/**
* Called when the fragment is no longer in use. This is called
* after @link #onStop() and before @link #onDetach().
*/
public void onDestroy()
mCalled = true;
//Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
// + " mLoaderManager=" + mLoaderManager);
if (!mCheckedForLoaderManager)
mCheckedForLoaderManager = true;
mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
if (mLoaderManager != null)
mLoaderManager.doDestroy();
2、ViewPager中的适配器使用FragmentPagerAdapter
package com.example.yu.viewpager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.example.yu.baseactivity.R;
import com.example.yu.viewpager.fragment.Fragment1;
import com.example.yu.viewpager.fragment.Fragment2;
import com.example.yu.viewpager.fragment.Fragment3;
import com.example.yu.viewpager.fragment.Fragment4;
import com.example.yu.viewpager.fragment.Fragment5;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends FragmentActivity
private ViewPager viewPager;
private MyFragemtAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
List<Fragment> fragments = new ArrayList<Fragment>();
fragments.add(new Fragment1());
fragments.add(new Fragment2());
fragments.add(new Fragment3());
fragments.add(new Fragment4());
fragments.add(new Fragment5());
adapter = new MyFragemtAdapter(getSupportFragmentManager(), fragments);
//设置缓存page的个数 2*n+1;
viewPager.setOffscreenPageLimit(1);
viewPager.setAdapter(adapter);
class MyFragemtAdapter extends FragmentPagerAdapter
private List<Fragment> mFragments;
public MyFragemtAdapter(FragmentManager fm, List<Fragment> fragments)
super(fm);
mFragments = fragments;
@Override
public Fragment getItem(int position)
return mFragments.get(position);
@Override
public int getCount()
return mFragments.size();
Fragment1示例代码如下(其他四个也都一样)
package com.example.yu.viewpager.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.yu.baseactivity.R;
/**
* Created by yu on 2016/6/12.
*/
public class Fragment1 extends Fragment
public static final String TAG = "Fragment1";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment1, container, false);
return view;
@Override
public void onDestroyView()
super.onDestroyView();
Log.i(TAG, "fragment is onDestroyView()");
@Override
public void onDestroy()
super.onDestroy();
Log.i(TAG, "fragment is onDestroy()");
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
Log.i(TAG, "fragment is onCreate()");
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "fragment is onActivityCreated()");
3、ViewPager中的适配器使用FragmentStatePagerAdapter
其他代码都不动,只修改适配器类型为FragmentStatePagerAdapter
class MyFragemtAdapter extends FragmentStatePagerAdapter
private List<Fragment> mFragments;
public MyFragemtAdapter(FragmentManager fm, List<Fragment> fragments)
super(fm);
mFragments = fragments;
@Override
public Fragment getItem(int position)
return mFragments.get(position);
@Override
public int getCount()
return mFragments.size();
从Log日志分析
以上是关于ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter的主要内容,如果未能解决你的问题,请参考以下文章
LinearLayout 中的 ViewPager ListView。滑动 ViewPager 应该滑动整个页面吗?
如何在viewPager的视图顶部使用nestedScrollView中的viewpager