目录
一.Fragment详解
一.Fragment基础
1.Fragment
Fragment为什么会出现,它其实是android3.0的时候引入的,可以翻译为“碎片” “片段”起初它主要是给大屏幕上设备上更灵活的展现UI所设计的。
如上图,左边展现的是平板电脑上的使用场景,而在实际项目开发中,使用频率更高的是右边的场景,右边的图中,左右两个Activity包含了各自的Fragment,Activity A通过 方法启动 Activity B时,实际上启动的是Fragment B。所以说我们一般会在一个Activity中嵌套多个Fragment,来进行UI 数组间的切换,一般用到的模式是Fragment+ViewPager。 Fragment相比Activity 更节省内存,同时UI的切换效果更加舒适, Fragment有自己的生命周期,同时它可以动态,灵活的加载Activity。但是Fragment并不是像Activity一样完全独立的,它虽然有自己的生命周期,但它必须依附Activity,同时它要加载到Activity当中。
2.Fragment加载到Activity的两种方式
1.静态添加:添加Fragment到Activity的布局文件当中
2.动态添加:动态在Activity中添加Fragment
静态加载就是把Fragment作为一个xml的标签加到Activity布局当中。
常用的方法就是动态添加
首先在布局文件中放一个FrameLayout,方便在Activity中可以动态添加不同的Fragment
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.bsoft.fragmentdemo.MainActivity">
<FrameLayout
android:id="@+id/fl_demo"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
然后在Activity中动态添加Fragment
//步骤1 : 添加FragmentTransaction的实例
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
//步骤2 :用add()方法加上Fragment的对象FirstFragment
FirstFragment firstFragment = new FirstFragment();
transaction.add(R.id.fl_demo,firstFragment);
//步骤3 : 调用commit()方法使FragmentTransaction实例的改变生效。
transaction.commit();
3.FragmentPagerAdapter与FragmentStatePagerAdapter区别
FragmentPagerAdapter适用于页面较少的情况。
FragmentStatePagerAdapter适用于页面较多的情况。
FragmentPagerAdapter源码中的destroyItem方法:
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);
}
它最后一行调用的是 FragmentTransaction的detach方法。detach并不是真正的内存回收,它只是把Fragment的UI和Activity的UI脱离开来,并不回收内存。
FragmentStatePagerAdapter源码中的destroyItem方法:
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object;
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
+ " v=" + ((Fragment)object).getView());
while (mSavedState.size() <= position) {
mSavedState.add(null);
}
mSavedState.set(position, fragment.isAdded()
? mFragmentManager.saveFragmentInstanceState(fragment) : null);
mFragments.set(position, null);
//在这里
mCurTransaction.remove(fragment);
}
mCurTransaction.remove(fragment),在FragmentStatePagerAdapter里面是真正释放了fragment内存。所以说明了FragmentStatePagerAdapter比FragmentPagerAdapter更节省内存的。
二.Fragment生命周期
1.Fragment生命周期与Activity生命周期的对比
2.Fragment从启动到销毁生命周期全过程
跟记忆Activity生命周期一样,Fragment的生命周期也需要灵活的来记忆
Fragment 创建时会调用:
onAttach() -> onCreate() -> onCreateView() -> onActivityCreated()
onAttach():在Fragment 与 Activity关联之后所回调的
onCreate() : 是在初次创建Fragment时候调用
注:这里的onCreate方法看起来和Activity中的onCreate方法一样。但是这个方法只是用来创建Fragment,此时的Activity还并没有被创建完成。
onCreateView():是系统在Fragment首次绘制用户界面时候调用的这个方法
注:如果想要为这个Fragment绘制UI界面,从该方法返回的View必须是Fragment布局的根视图。
在onCreateView()方法调用之后会调用onViewCreated()方法
onViewCreated():表明Fragment的UI界面已经完全绘制好了,调用这个方法可以初始化控件资源。
onActivityCreated():这个方法是在Activity的onCreat()方法调用之后才可以被调用。也就是在Activity被渲染绘制成功以后的调用方法
Fragment被用户可见后调用
onStart() -> onResume()
onStart():表示Fragment可见了
onResume():表示Fragment可以跟用户进行交互了(点击,滑动等操作)
到这里已经完成了Fragment从启动到展现的操作。
当要Fragment被销毁
onPause() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach()
onPause():系统将此方法作为用户离开Fragment的第一个信号(但并不总是意味着此Fragment会被销毁)进行调用。 通常可以在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。
onDestroyView():表示这个Fragment即将结束,会被保存。
onDetach():Fragment和Activity解除关联的时候调用
到此,我们完整的走完一Fragment的生命周期。
还有一些其他场景时Fragment调用的生命周期
屏幕灭掉
onPause() -> onSaveInstanceState() -> onStop()
屏幕解锁
onStart() -> onResume()
切换到其他Fragment
onPause() -> onStop() -> onDestroyView()
切换回本身的Fragment
onCreateView() -> onActivityCreated() -> onStart() -> onResume()
回到桌面
onPause() -> onSaveInstanceState() -> onStop()
回到应用
onStart() -> onResume()
三.Fragment通信
1.在Fragment中调用Activity中的方法
(getActivity)只要调用getActivity方法,就可以获取到Activity中的方法
2.在Activity中调用Fragment中的方法
(接口回调)在Fragment中创建个接口,然后由Activity实现。这样就能完成在Activity中调用Fragment中的方法
3.在Fragment中调用Fragment中的方法
(findFragmentById)首先可以通过 getActivity获取Activity的方法,然后通过findFragmentById获取到Activity所对应的另外一个Fragment的方法,这样就能完成Fragment与Fragment的通信
四.Fragment的replace,add,remove方法
replace():替换Fragment实例。
add():将一个Fragment实例添加到添加到Activity最上层
remove():将Fragment实例从Activity队列中删除