个人笔记-Fragment用法及其生命周期

2,460 阅读3分钟

声明

该文章只作为一个笔记,排版杂乱,看文前慎重!

Fragment的用法及其生命周期

相关链接:

  1. 深刻的理解Fragment生命周期 都在做什么_网络_svenWang_的专栏-CSDN博客

Fragment 的静态生命周期

Fragment 动态添加

注意:

  1. 第一次的动态添加使用add,接下来的使用replace.
  2. 除了onCreateView,其他的所有生命周期方法如果你重写了,必须调用父类对于该方法的实现。

我的总结

生命周期测试

Fragment动态显示主要有两种方式

  1. 通过 replace、add方法动态添加
//替代Fragment
void replaceFragment1(Fragment fragment) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.three_activity_fragment_layout, fragment);
        transaction.commit();
}
//此时按返回键会将Fragment最上层的出栈,而不是退出活动
// 此种方法下Fragment如果
void replaceFragment2(Fragment fragment) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.three_activity_fragment_layout, fragment);
       transaction. addToBackStack(null);//添加到栈中
        transaction.commit();
}
/**
假设有FragmentA和FragmentB
在此种方法下
如果 当前显示是FragmentA ,此时调用replaceFragment2替换  Fragment A,此时FragmentA的生命周期不会有任何变化,但是如果此时按返回键返回的仍然是FragmentA。
如果当前显示是FragmentA,此时调用replaceFragment2替换FragmentB,此时FragmentA的生命周期走到onDetech,FragmentB从onAttach走到onResume,之后如果按下返回键,此时FragmentB生命周期走到onDetech,FragmentA生命周期从onAttchch走到onResume,由此可以看出,在此种方法下,Fragment每次入栈出栈,都是判断当端下一个位于栈顶的Fragment是否与当前Fragment相同,如果不同,则销毁当前栈顶Fragment,并且创建新的Fragment,如果相同,则Fragment生命周期无变化 
**/
//添加Fragment
//注意,如果Fragment已经添加了,再次添加会报错
//如果添加了多个就会产生重叠,因为Fragment的特性就是每次添加的布局都在页面左上角
//
// Fragment already added: Test1Fragment
void addFragment(Fragment fragment){
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.three_activity_fragment_layout,fragment);
       transaction.commit();
}

2.

# 活动ThreeActivity创建,且在ThreeActivity中动态添加了Test1Fragment
com.example.applicationtest I/ThreeActivity: onCreate: test3
com.example.applicationtest I/Test1Fragment: onAttach: test3
com.example.applicationtest I/ThreeActivity: onAttachFragment: test3 
com.example.applicationtest I/Test1Fragment: onCreate: test3
com.example.applicationtest I/Test1Fragment: onCreateView: test3
com.example.applicationtest I/Test1Fragment: onActivityCreated: test3
com.example.applicationtest I/Test1Fragment: onStart: test3
com.example.applicationtest I/ThreeActivity: onStart: test3
com.example.applicationtest I/ThreeActivity: onResume: test3
com.example.applicationtest I/Test1Fragment: onResume: test3 
# 从上可以看出Fragment生命周期是受到Activity影响的,
#Activity的onAttchFragment是在Fragment的onAttch之后调用的

# 点击按钮切换成Test2Fragment
# 可以 看到Test1在被替换后,其生命周期走向了onDestroy,但是还没有走到oDetech
com.example.applicationtest I/Test2Fragment: onAttach: test3
com.example.applicationtest I/ThreeActivity: onAttachFragment: test3
com.example.applicationtest I/Test2Fragment: onCreate: test3
com.example.applicationtest I/Test1Fragment: onPause: test3
com.example.applicationtest I/Test1Fragment: onStop: test3
com.example.applicationtest I/Test1Fragment: onDestroyView: test3
com.example.applicationtest I/Test1Fragment: onDestroy: test3
com.example.applicationtest I/Test2Fragment: onCreateView: test3
com.example.applicationtest I/Test2Fragment: onActivityCreated: test3
com.example.applicationtest I/Test2Fragment: onStart: test3
com.example.applicationtest I/Test2Fragment: onResume: test3

Fragment布局应用及其要点

 @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.i(TAG, "onCreateView: test3");
        View view=inflater.inflate(R.layout.fragment_test1,container,false);
        //此处attachToRoot,不能为true,否则会报错
        return view;
    }

如上代码所示,在onCreateView中引入布局,但是要注意attachToRoot参数必须是为false,否则会报错,在调用onStart提示 child已经有了parent.

The specified child already has a parent. You must call removeView() on the child's parent first.

Fragment 更好的切换方法

Fragment 使用hide和show,使用onHiddenChanged代替执行生命周期_移动开发_Losileeya-CSDN博客

show,hide方法

为了避免布局的重复创建和加载,采用如下方式,能够更好更快的切换布局,此种方法不会走Fragment的生命周期

/**
     * 修改显示的内容 不会重新加载
     * to 下一个fragment
     * mContent 当前的fragment
     */
    private void switchContent(Fragment to) {
        if (mContent != to) {
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            if (!to.isAdded()) { // 判断是否被add过
                // 隐藏当前的fragment,将 下一个fragment 添加进去
                    transaction.hide(mContent).add(R.id.layout_content, to).commit(); 
            } else {
                // 隐藏当前的fragment,显示下一个fragment
                    transaction.hide(mContent).show(to).commit(); 
            }
            mContent = to;
        }

    }

为了监听Fragment的状态转换,可以重写Fragment的onHinddenChanged方法,通过判断Fragment是否隐藏,手动模式生命周期的onPause,onResume。 onHiddenChanged方法

  @Override
  public void onHiddenChanged(boolean hidden) {
      super.onHiddenChanged(hidden);
      if (hidden) {   // 不在最前端显示 相当于调用了onPause();
          return;
      }else{  // 在最前端显示 相当于调用了onResume();
         //网络数据刷新
      }
  }