码迷,mamicode.com
首页 > 其他好文 > 详细

Fragment管理最佳实践

时间:2016-04-29 16:14:09      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

现在的app视图中tab+fragment是最常用的一种布局,但是如果使用才是更简洁更有效的呢?下面通过一个demo的分类测试来分析下:

add remove replace detach attach hide show这些方法的使用对Fragment生命周期的影响分析:
顺便分析下Fragment所依赖的Activity的生命周期;

测试代码如下:
MainActivity的代码如下:

package com.testfragmentlifecircle;

import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends FragmentActivity {
    private static final String TAG = "test-MainActivity";

    // 首页
    private IndexFragment indexFragment;
    // 我的页面
    private MineFragment mineFragment;
    // 更多页面
    private MoreFragment moreFragment;
    private TextView[] textviews;
    private Fragment[] fragments;
    public int index;
    // 当前fragment的index
    private int currentTabIndex;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "--onCreate");
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        textviews = new TextView[3];
        textviews[0] = (TextView) findViewById(R.id.index_text);
        textviews[1] = (TextView) findViewById(R.id.mine_text);
        textviews[2] = (TextView) findViewById(R.id.more_text);
        textviews[0].setSelected(true);
        indexFragment = new IndexFragment();
        mineFragment = new MineFragment();
        moreFragment = new MoreFragment();
        fragments = new Fragment[]{indexFragment, mineFragment, moreFragment};
        // 添加显示第一个fragment
        /*用add、hide和show测试的初始化的代码*/
//        getSupportFragmentManager().beginTransaction()
//                .add(R.id.fragment_container, indexFragment)
//                .add(R.id.fragment_container, mineFragment)
//                .add(R.id.fragment_container, moreFragment)
//                .show(indexFragment).hide(mineFragment).hide(moreFragment)
//                .commit();
        /*用replace测试的初始化的代码*/
//        getSupportFragmentManager().beginTransaction()
//                .replace(R.id.fragment_container, indexFragment)
//                .addToBackStack(null)
//                .commit();
        /*用attach和dettach测试的初始化的代码*/
        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, indexFragment)
                .add(R.id.fragment_container, mineFragment)
                .add(R.id.fragment_container, moreFragment)
                .attach(indexFragment)
                .detach(mineFragment)
                .detach(moreFragment)
                .commit();
    }

    private void refreshTab() {
        if (currentTabIndex != index) {
            FragmentTransaction trx = getSupportFragmentManager()
                    .beginTransaction();
            /*用add、hide和show测试的切换Fragment的代码*/
//            for (int i = 0; i < fragments.length; i++) {
//                if (!fragments[i].isAdded()) {
//                    trx.add(R.id.fragment_container, fragments[i]);
//                }
//                if (i != index) {
//                    trx.hide(fragments[i]);
//                } else {
//                    trx.show(fragments[i]);
//                }
//            }
            /*用replace测试的切换Fragment的代码*/
//            trx.addToBackStack(null);
//            trx.replace(R.id.fragment_container, fragments[index]);
            /*用attach和dettach测试的切换Fragment的代码*/
            for (int i = 0; i < fragments.length; i++) {
                if (!fragments[i].isAdded()) {
                    trx.add(R.id.fragment_container, fragments[i]);
                }
                if (i != index) {
                    trx.detach(fragments[i]);
                } else {
                    trx.attach(fragments[i]);
                }
            }
            trx.commit();

            textviews[currentTabIndex].setSelected(false);
            textviews[index].setSelected(true);
            currentTabIndex = index;
        }
    }

    public void onTabClicked(View view) {
        switch (view.getId()) {
            case R.id.index:
                if (0 != index) {
                    index = 0;
                }
                break;
            case R.id.mine:
                if (1 != index) {
                    index = 1;
                }
                break;
            case R.id.more:
                if (2 != index) {
                    index = 2;
                }
                break;
        }
        refreshTab();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        Log.e(TAG, "--onBackPressed");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "--onDestroy");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "--onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "--onResume");
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e(TAG, "--onNewIntent");
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.e(TAG, "--onPostResume");
    }

    @Override
    protected void onResumeFragments() {
        super.onResumeFragments();
        Log.e(TAG, "--onResumeFragments");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(TAG, "--onSaveInstanceState");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG, "--onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "--onStop");
    }

    @Override
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        Log.e(TAG, "--onAttachFragment");
    }

}

BaseFragment代码如下:

package com.testfragmentlifecircle;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * 作 者: yc
 * 创 建:2016/4/27-11:52
 * 版 本:
 */
public class BaseFragment extends Fragment {

    protected final String TAG = "test-" + this.getClass().getSimpleName();

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.e(TAG,"--onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG,"--onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.e(TAG,"--onCreateView");
        TextView textView = new TextView(getContext());
        textView.setText(TAG);
        return textView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.e(TAG,"--onActivityCreated");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.e(TAG,"--onStart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.e(TAG,"--onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.e(TAG,"--onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.e(TAG,"--onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.e(TAG,"--onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG,"--onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.e(TAG,"--onDetach");
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        Log.e(TAG,"--onHiddenChanged--hidden="+hidden);
        super.onHiddenChanged(hidden);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(TAG,"--onSaveInstanceState");
    }
}

三个Fragment分别为IndexFragment、MineFragment和MoreFragment,代码分别如下:

package com.testfragmentlifecircle;

/**
 * 作 者: yc
 * 创 建:2016/4/27-12:36
 * 版 本:
 */
public class IndexFragment extends BaseFragment {

}
package com.testfragmentlifecircle;

/**
 * 作 者: yc
 * 创 建:2016/4/27-12:36
 * 版 本:
 */
public class MineFragment extends BaseFragment {

}
package com.testfragmentlifecircle;

/**
 * 作 者: yc
 * 创 建:2016/4/27-12:36
 * 版 本:
 */
public class MoreFragment extends BaseFragment {

}

MainActivity布局activity_main.xml代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/other_bg"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/main_bottom"
        android:layout_width="match_parent"
        android:layout_height="48dip"
        android:layout_alignParentBottom="true"
        android:background="@color/index_tab_color"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <RelativeLayout
            android:id="@+id/index"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:onClick="onTabClicked"
            android:paddingBottom="2dip"
            android:paddingTop="5dip">

            <TextView
                android:id="@+id/index_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="2dp"
                android:text="@string/index"
                android:textColor="@color/clicked_text_color"
                android:textSize="10sp" />
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/mine"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:onClick="onTabClicked"
            android:paddingBottom="2dip"
            android:paddingTop="5dip">

            <TextView
                android:id="@+id/mine_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="2dp"
                android:text="@string/mine"
                android:textColor="@color/clicked_text_color"
                android:textSize="10sp" />
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/more"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:onClick="onTabClicked"
            android:paddingBottom="2dip"
            android:paddingTop="5dip">

            <TextView
                android:id="@+id/more_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="2dp"
                android:text="@string/more"
                android:textColor="@color/clicked_text_color"
                android:textSize="10sp" />
        </RelativeLayout>
    </LinearLayout>

    <View
        android:id="@+id/view_temp"
        android:layout_width="match_parent"
        android:layout_height="0.1dp"
        android:layout_above="@id/main_bottom"
        android:background="@color/index_divider_color" />

    <RelativeLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/view_temp" />

</RelativeLayout>

分类测试及日志分析:
1.通过add添加,通过hide和show控制Fragment的隐藏和显示的切换
1.1——————————————-初始化,初始显示IndexFragment,隐藏MineFragment和MoreFragment:
E/test-MainActivity: –onCreate
/com.testfragmentlifecircle E/test-MineFragment: –onHiddenChanged–hidden=true
/com.testfragmentlifecircle E/test-MoreFragment: –onHiddenChanged–hidden=true
/com.testfragmentlifecircle E/test-IndexFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-IndexFragment: –onCreate
/com.testfragmentlifecircle E/test-IndexFragment: –onCreateView
/com.testfragmentlifecircle E/test-IndexFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-MineFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-MineFragment: –onCreate
/com.testfragmentlifecircle E/test-MineFragment: –onCreateView
/com.testfragmentlifecircle E/test-MineFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-MoreFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-MoreFragment: –onCreate
/com.testfragmentlifecircle E/test-MoreFragment: –onCreateView
/com.testfragmentlifecircle E/test-MoreFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
/com.testfragmentlifecircle E/test-MineFragment: –onStart
/com.testfragmentlifecircle E/test-MoreFragment: –onStart
E/test-MainActivity: –onStart
E/test-MainActivity: –onResume
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
/com.testfragmentlifecircle E/test-MineFragment: –onResume
/com.testfragmentlifecircle E/test-MoreFragment: –onResume
E/test-MainActivity: –onResumeFragments
E/test-MainActivity: –onPostResume
结论:初始化隐藏的Fragment会回调onHiddenChanged,初始化显示的不会回调onHiddenChanged,因为add进去的Fragment的默认就是显示的,
所以add之后再调用hide的时候从显示变成了隐藏才会回调onHiddenChanged方法。
结论:onAttachFragment会在每个Fragment关联(onAttach)之后回调,onResumeFragments会在所有Fragment初始化完成之后回调一次
1.2——————————————-退出应用,即退出MainActivity:
E/test-MainActivity: –onBackPressed
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
/com.testfragmentlifecircle E/test-MineFragment: –onPause
/com.testfragmentlifecircle E/test-MoreFragment: –onPause
E/test-MainActivity: –onPause
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
/com.testfragmentlifecircle E/test-MineFragment: –onStop
/com.testfragmentlifecircle E/test-MoreFragment: –onStop
E/test-MainActivity: –onStop
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroyView
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroy
/com.testfragmentlifecircle E/test-IndexFragment: –onDetach
/com.testfragmentlifecircle E/test-MineFragment: –onDestroyView
/com.testfragmentlifecircle E/test-MineFragment: –onDestroy
/com.testfragmentlifecircle E/test-MineFragment: –onDetach
/com.testfragmentlifecircle E/test-MoreFragment: –onDestroyView
/com.testfragmentlifecircle E/test-MoreFragment: –onDestroy
/com.testfragmentlifecircle E/test-MoreFragment: –onDetach
E/test-MainActivity: –onDestroy
结论:走完退出流程
结论:
1.3——————————————-从IndexFragment切换到MineFragment:
/com.testfragmentlifecircle E/test-IndexFragment: –onHiddenChanged–hidden=true
/com.testfragmentlifecircle E/test-MineFragment: –onHiddenChanged–hidden=false
结论:Fragment页面之间通过hide和show进行切换,并不会回调Fragment的任何生命周期方法,只会回调onHiddenChanged
结论:
1.4——————————————-从前台切换到后台:
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
/com.testfragmentlifecircle E/test-MineFragment: –onPause
/com.testfragmentlifecircle E/test-MoreFragment: –onPause
E/test-MainActivity: –onPause
E/test-MainActivity: –onSaveInstanceState
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
/com.testfragmentlifecircle E/test-MineFragment: –onStop
/com.testfragmentlifecircle E/test-MoreFragment: –onStop
E/test-MainActivity: –onStop
结论:当所依赖的MainActivity切换到后台,Fragment同样会执行对应的生命周期方法:onPause–onStop
结论:这里说明一点,这里没有打印这些Fragment的onSaveInstanceState方法的回调,其实这个和MainActivity的执行是一致的
1.5——————————————-从后台切换到前台:
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
/com.testfragmentlifecircle E/test-MineFragment: –onStart
/com.testfragmentlifecircle E/test-MoreFragment: –onStart
E/test-MainActivity: –onStart
E/test-MainActivity: –onResume
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
/com.testfragmentlifecircle E/test-MineFragment: –onResume
/com.testfragmentlifecircle E/test-MoreFragment: –onResume
E/test-MainActivity: –onResumeFragments
E/test-MainActivity: –onPostResume
结论:当所依赖的MainActivity切换到前台,Fragment同样会执行对应的生命周期方法:onStart–onResume
结论:
1.6 大总结:在初始化和前后台切换的过程中Fragment和MainActivity对应生命周期的回调是一致的,
特殊点在于Fragment之间来回切换并不会回调Fragment和MainActivity的任何生命周期方法,但是会
回调onHiddenChanged方法,并且初始化过程中只有add之后再调用hide的时候从显示变成了隐藏才会
回调onHiddenChanged方法,这样如果我们想要在摸个Fragment显示的时候做一些和onResume方法中同
样的初始化工作就不会发生重复和冲突,所以我们可以在Fragment显示的时候在onHiddenChanged的

hidden=false的时候做onResume中同样的初始化工作。(由此可见Google大佬们的设计之精妙)

用这种方法就能实现Fragment切换的最佳实践:切换显示装填的时候并不会销毁或者重新创建,而是
每个Fragment都始终加载完成并保存在内存中,并且在任何时候进行显示状态的切换都有回调可以做
初始化或者收尾工作:1.Fragment之间切换可以在onHiddenChanged中做工作 2.其它情况下都有对应
的生命周期方法可供回调

2.通过replace方法控制Fragment的隐藏和显示的切换
2.1——————————————-初始化,初始显示IndexFragment:
E/test-MainActivity: –onCreate
/com.testfragmentlifecircle E/test-IndexFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-IndexFragment: –onCreate
/com.testfragmentlifecircle E/test-IndexFragment: –onCreateView
/com.testfragmentlifecircle E/test-IndexFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
E/test-MainActivity: –onStart
E/test-MainActivity: –onResume
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
E/test-MainActivity: –onResumeFragments
E/test-MainActivity: –onPostResume
结论:
结论:
2.2——————————————-从IndexFragment切换到MineFragment:(直接replace)
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroyView
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroy
/com.testfragmentlifecircle E/test-IndexFragment: –onDetach
/com.testfragmentlifecircle E/test-MineFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-MineFragment: –onCreate
/com.testfragmentlifecircle E/test-MineFragment: –onCreateView
/com.testfragmentlifecircle E/test-MineFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-MineFragment: –onStart
/com.testfragmentlifecircle E/test-MineFragment: –onResume
———————————————-再切换回IndexFragment
/com.testfragmentlifecircle E/test-MineFragment: –onPause
/com.testfragmentlifecircle E/test-MineFragment: –onStop
/com.testfragmentlifecircle E/test-MineFragment: –onDestroyView
/com.testfragmentlifecircle E/test-MineFragment: –onDestroy
/com.testfragmentlifecircle E/test-MineFragment: –onDetach
/com.testfragmentlifecircle E/test-IndexFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-IndexFragment: –onCreate
/com.testfragmentlifecircle E/test-IndexFragment: –onCreateView
/com.testfragmentlifecircle E/test-IndexFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
结论:replace内部实现,就是remove掉之前所添加(add)过的所有Fragment,然后再添加并显示当前Fragment,
所以之前的Fragment会被彻底删除掉。
结论:
2.3——————————————-从IndexFragment切换到MineFragment:(给FragmentTransaction设置addToBackStack(null)之后再replace)
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroyView
/com.testfragmentlifecircle E/test-MineFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-MineFragment: –onCreate
/com.testfragmentlifecircle E/test-MineFragment: –onCreateView
/com.testfragmentlifecircle E/test-MineFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-MineFragment: –onStart
/com.testfragmentlifecircle E/test-MineFragment: –onResume
———————————————-再切换回IndexFragment
/com.testfragmentlifecircle E/test-MineFragment: –onPause
/com.testfragmentlifecircle E/test-MineFragment: –onStop
/com.testfragmentlifecircle E/test-MineFragment: –onDestroyView
/com.testfragmentlifecircle E/test-IndexFragment: –onCreateView
/com.testfragmentlifecircle E/test-IndexFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
结论:这种实现方式即没有彻底销毁Fragment对象,还能在Fragment切换的时候正常回调onResume方法,比较接近最佳实践,
但是只是没有彻底销毁Fragment对象,而是把对象存储到内存中,但是Fragment中的试图仍需要重新构建。
我们通常复写Fragment就是从onCreateView方法开始,等于说对我们而言这些页面初始化工作每次显示都需要重来,只是framework层
不需要彻底销毁Fragment对象而已,所以这种方式可以解决生命周期一致性问题,但是并不能很好的解决Fragment之间相互切换的时候
的重新加载问题,并不是完美的最佳实践。
结论:

3.通过dettach和attach方法控制Fragment的隐藏和显示的切换
3.1——————————————-初始化,初始显示IndexFragment:
E/test-MainActivity: –onCreate
/com.testfragmentlifecircle E/test-IndexFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-IndexFragment: –onCreate
/com.testfragmentlifecircle E/test-MineFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-MineFragment: –onCreate
/com.testfragmentlifecircle E/test-MoreFragment: –onAttach
E/test-MainActivity: –onAttachFragment
/com.testfragmentlifecircle E/test-MoreFragment: –onCreate
/com.testfragmentlifecircle E/test-IndexFragment: –onCreateView
/com.testfragmentlifecircle E/test-IndexFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
E/test-MainActivity: –onStart
E/test-MainActivity: –onResume
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
E/test-MainActivity: –onResumeFragments
E/test-MainActivity: –onPostResume
结论:只有初始化和MainActivity想关联(attach)的Fragment才会走完显示的生命周期,而初始化和MainActivity
不关联(dettach)的Fragment只回调onAttach和onCreate就完了,这说明不关联的Fragment已经创建好并且存储在
内存中
结论:
3.2——————————————-退出应用,即退出MainActivity:
E/test-MainActivity: –onBackPressed
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
E/test-MainActivity: –onPause
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
E/test-MainActivity: –onStop
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroyView
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroy
/com.testfragmentlifecircle E/test-IndexFragment: –onDetach
/com.testfragmentlifecircle E/test-MineFragment: –onDestroy
/com.testfragmentlifecircle E/test-MineFragment: –onDetach
/com.testfragmentlifecircle E/test-MoreFragment: –onDestroy
/com.testfragmentlifecircle E/test-MoreFragment: –onDetach
E/test-MainActivity: –onDestroy
结论:
结论:
3.3——————————————-从IndexFragment切换到MineFragment:
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
/com.testfragmentlifecircle E/test-IndexFragment: –onDestroyView
/com.testfragmentlifecircle E/test-MineFragment: –onCreateView
/com.testfragmentlifecircle E/test-MineFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-MineFragment: –onStart
/com.testfragmentlifecircle E/test-MineFragment: –onResume
———————————————-再切换回IndexFragment
/com.testfragmentlifecircle E/test-IndexFragment: –onCreateView
/com.testfragmentlifecircle E/test-IndexFragment: –onActivityCreated
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
/com.testfragmentlifecircle E/test-MineFragment: –onPause
/com.testfragmentlifecircle E/test-MineFragment: –onStop
/com.testfragmentlifecircle E/test-MineFragment: –onDestroyView
结论:由此可见attach和dettach的使用,和replace+addToBackStack(null)的使用效果是一样的:
当前没有显示的Fragment的对象并没有被彻底销毁,而是存储在回收栈中,当需要显示的时候只需要重新构建布局,
从onDestroyView开始就行了。所以对于即不要每次都重新加载有想要生命周期一致的情况,这同样不是完美的最佳实践。
结论:
3.4——————————————-从前台切换到后台:
/com.testfragmentlifecircle E/test-IndexFragment: –onPause
E/test-MainActivity: –onPause
/com.testfragmentlifecircle E/test-IndexFragment: –onSaveInstanceState
/com.testfragmentlifecircle E/test-MineFragment: –onSaveInstanceState
/com.testfragmentlifecircle E/test-MoreFragment: –onSaveInstanceState
E/test-MainActivity: –onSaveInstanceState
/com.testfragmentlifecircle E/test-IndexFragment: –onStop
E/test-MainActivity: –onStop
———————————————-再切换回前台
/com.testfragmentlifecircle E/test-IndexFragment: –onStart
E/test-MainActivity: –onStart
E/test-MainActivity: –onResume
/com.testfragmentlifecircle E/test-IndexFragment: –onResume
E/test-MainActivity: –onResumeFragments
E/test-MainActivity: –onPostResume
结论:只有当前处于关联状态的Fragment会执行和MainActivity一致的生命周期
结论:

4.总结:Fragment管理的最佳实践:add、hide和show,并通过onHiddenChanged完成Fragment之间切换时候的初始化工作。
实践目标:
1.每个Fragment显示状态切换的时候既不会销毁和重建对象,也不会销毁和重建布局
2.通过onHiddenChanged完成Fragment之间切换完成前后台切换时候onResume里面需要做的初始化工作,弥补了生命周期不
一致所带来的Fragment之间切换时候的初始化工作不能完全同步的问题

API不再逐个分析,参考:
http://www.pocketdigi.com/20141006/1385.html
http://blog.csdn.net/buaaroid/article/details/48265105

Fragment管理最佳实践

标签:

原文地址:http://blog.csdn.net/u013168615/article/details/51263218

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!