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日志分析
这里写图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值