天天看點

ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter1、首先明确Fragment的生命周期2、ViewPager中的擴充卡使用FragmentPagerAdapter3、ViewPager中的擴充卡使用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,什麼時候可以加載資料。

ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter1、首先明确Fragment的生命周期2、ViewPager中的擴充卡使用FragmentPagerAdapter3、ViewPager中的擴充卡使用FragmentStatePagerAdapter

幾個重要容易模糊的生命周期

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的個數 *n+;
        viewPager.setOffscreenPageLimit();

        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()");
    }
}
           
ViewPager中的FragmentPagerAdapter,FragmentStatePagerAdapter1、首先明确Fragment的生命周期2、ViewPager中的擴充卡使用FragmentPagerAdapter3、ViewPager中的擴充卡使用FragmentStatePagerAdapter

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,FragmentStatePagerAdapter1、首先明确Fragment的生命周期2、ViewPager中的擴充卡使用FragmentPagerAdapter3、ViewPager中的擴充卡使用FragmentStatePagerAdapter

繼續閱讀