Fragment详解

2019-05-22  本文已影响0人  _Rice_
image.png

特点

优势

1、代码复用。

Activity用来管理Fragment。因为一个Fragment可以被多个Activity嵌套,有个共同的业务模块就可以复用了

2、模块化

Fragment具有自己生命周期,是模块化UI的良好组件。

2、可控性。

Fragment的生命周期是寄托到Activity中,Fragment可以被Attach添加和Detach释放。

3、切换灵活。

Fragments是view controllers,它们包含可测试的,解耦的业务逻辑块,由于Fragments是构建在views之上的,而views很容易实现动画效果,因此Fragments在屏幕切换时具有更好的控制。

4、可控性。

Fragment可以像普通对象那样自由的创建和控制,传递参数更加容易和方便,也不用处理系统相关的事情,显示方式、替换、不管是整体还是部分,都可以做到相应的更改。

生命周期

image.png

可以看出Fragment生命周期与Activity类似

解释如下:

上面的方法中,只有onCreateView()在重写时不用写super方法,其他都需要。

因为Fragment依赖Activity,那么Fragment和Activity的生命周期可谓是息息相关,如下图所示

image.png

Activity的FragmentManager负责调用队列中Fragment的生命周期方法,只要Fragment的状态与Activity的状态保持了同步,托管Activity的FragmentManager便会继续调用其他生命周期方法以继续保持Fragment与Activity的状态一致。

打开页面

Activity-onCreate(begin),Fragment-onAttach-onCreate-onCreateView-onViewCreated,Activity-onCreate(end),Fragment-onActivityCreated,Activity-onStart,Fragment-onStart,Activity-onResume,Fragment-onResume

按下HOME键

Fragment-onPause,Activity-onPause,Fragment-onStop,Activity-onStop

重新打开页面

Activity-onRestart-onStart,Fragment-onStart,Activity-onResume,Fragment-onResume

按下返回键

Fragment-onPause,Activity-onPause,Fragment-onStop,Activity-onStop,Fragment-onDestroyView-onDestroy-onDetach,Activity-onDestroy

加载方式

静态加载

    <fragment
        android:id="@+id/f3"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:name="com.example.lenovo.mpplication.fragment.Fragment3"/>

动态加载

FragmentManager

Fragment的管理则交由FragmentActivity的FragmentManager来实现。

image.png

获取方式:

注意:在fragment创建childFragment的时候,需要注意的是:使用getChildFragmentManager() 使用getFragmentManager()会导致内存泄漏

常用API:

popBackStackImmediate相关的方法与上面逻辑是一样的与上面不同的是,在调用的时候会立即执行弹出。

FragmentTransaction

通过FragmentTransaction实现在Activity运行时可动态地加入、移除、交换Fragment

FragmentTransaction的主要方法介绍

针对在一个Activity中的某个Layout中切换Fragment,无非两种方法:

add(id, fragment)
remove(fragment)
replace(id, fragment)
show(fragment)
hide(fragment)
detach()
attach()
addToBackStack()

当移除或替换一个片段并向返回栈添加事务时,系统会停止(而非销毁)移除的片段。 如果用户执行回退操作进行片段恢复,该片段将重新启动。

具体实例可参看:Fragment的addToBackStack()使用

commit()
commitAllowingStateLoss()
commitNow()

commit(), commitNow()和commitAllowingStateLoss()区别分析

实例:

//addToBackStack
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment12, fragment1);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commitNow();


//添加Fragment到FragmentList中
private void addFragment(Fragment fragment, String tag){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.fragment_container,fragment,tag);
        transaction.commit();
    }

// 清空fragmentList的所有Fragment,替换成新的Fragment,注意Fragment里面的坑
private void replaceFragment(Fragment fragment, String tag){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.fragment_container,fragment,tag);
        transaction.commit();
    }

//移除指定的Fragment
private void removeFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.remove(fragment);
        transaction.commit();
    }

//把Fragment设置成显示状态,但是并没有添加到FragmentList中
private void showFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.show(fragment);
        transaction.commit();
    }

//把Fragment设置成显示状态,但是并没有添加到FragmentList中
private void hideFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.hide(fragment);
        transaction.commit();
    }

// 效果和show相近,创建视图,添加到containerid指定的Added列表,FragmentList依然保留,但是会引起生命周期的变化
private void attachFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.attach(fragment);
        transaction.commit();
    }

// 效果和hide相近,清除视图,从containerid指定的Added列表移除,FragmentList依然保留,但是会引起生命周期的变化
private void detachFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.detach(fragment);
        transaction.commit();
    }

数据传递

使用setArguments(Bundle args)传递,在onCreate中使用getArguments()取出。和Activity的Intent恢复机制类似。

常见坑

1、如果你需要在Fragment中用到宿主Activity对象,建议在你的基类Fragment定义一个Activity的全局变量,在onAttach中初始化,这不是最好的解决办法,但这可以有效避免一些意外Crash。

protected Activity mActivity;
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    this.mActivity = activity;
}

2、onHiddenChanged的回调时机

当使用add()+show(),hide()跳转新的Fragment时,旧的Fragment回调onHiddenChanged(),不会回调生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged()

推荐阅读:Fragment全解析系列(二):正确的使用姿势Fragment全解析系列(一):那些年踩过的坑

上一篇下一篇

猜你喜欢

热点阅读