Android开发之fragment

Android开发之fragment

一、初识fragment

fragment: 碎片,Android3.0新增概念,Activity界面中的一部分,可理解为模块化的Activity,支持动态灵活的的界面设计。

  • Fragment不能独立存在,必须嵌入到Activity中
  • Fragment具有自己的生命周期,接收它自己的事件,并可以在Activity运行时被添加或删除
  • Fragment的生命周期直接受所在的Activity的影响。当Activity暂停时,它拥有的所有Fragment都暂停
  • 本质上会产生一个FrameLayout,它加载的布局为其子布局

二、fragment生命周期详解

这里写图片描述

1 、方法详解

setUserVisibleHint():设置Fragment可见或者不可见时会调用此方法。在该方法里面可以通过调用getUserVisibleHint()获得Fragment的状态是可见还是不可见的,如果可见则进行懒加载操作。

onAttach():执行该方法时,Fragment与Activity已经完成绑定,该方法有一个Activity类型的参数,代表绑定的Activity,这时候你可以执行诸如mActivity = activity的操作。

onCreate():初始化Fragment。可通过参数savedInstanceState获取之前保存的值。

onCreateView():初始化Fragment的布局。加载布局和findViewById的操作通常在此函数内完成,但是不建议执行耗时的操作,比如读取数据库数据列表。

onActivityCreated():执行该方法时,与Fragment绑定的Activity的onCreate方法已经执行完成并返回,在该方法内可以进行与Activity交互的UI操作,所以在该方法之前Activity的onCreate方法并未执行完成,如果提前进行交互操作,会引发空指针异常。

onStart():执行该方法时,Fragment由不可见变为可见状态。

onResume():执行该方法时,Fragment处于活动状态,用户可与之交互。

onPause():执行该方法时,Fragment处于暂停状态,但依然可见,用户不能与之交互。

onSaveInstanceState():保存当前Fragment的状态。该方法会自动保存Fragment的状态,比如EditText键入的文本,即使Fragment被回收又重新创建,一样能恢复EditText之前键入的文本。
onStop():执行该方法时,Fragment完全不可见。

onDestroyView():销毁与Fragment有关的视图,但未与Activity解除绑定,依然可以通过onCreateView方法重新创建视图。通常在ViewPager+Fragment的方式下会调用此方法。

onDestroy():销毁Fragment。通常按Back键退出或者Fragment被回收时调用此方法。

onDetach():解除与Activity的绑定。在onDestroy方法之后调用。

2、Fragment生命周期执行流程(注意红色的不是生命周期方法):
Fragment创建:setUserVisibleHint()->onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume();
Fragment变为不可见状态(锁屏、回到桌面、被Activity完全覆盖):onPause()->onSaveInstanceState()->onStop();
Fragment变为部分可见状态(打开Dialog样式的Activity):onPause()->onSaveInstanceState();
Fragment由不可见变为活动状态:onStart()->OnResume();
Fragment由部分可见变为活动状态:onResume();
退出应用:onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()(注意退出不会调用onSaveInstanceState方法,因为是人为退出,没有必要再保存数据);
Fragment被回收又重新创建:被回收执行onPause()->onSaveInstanceState()->onStop()->onDestroyView()->onDestroy()->onDetach(),重新创建执行onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->setUserVisibleHint();
横竖屏切换:与Fragment被回收又重新创建一样。

三、fragment的基本使用

由于fragment作为activity的一部分,一般是讲fragment添加到activity中使用,有两种方法:

1、在activity的布局文件中静态添加

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/text">

    <!--该fragment类定义在包名为"com.skywang.app"中的FragmentLayoutTest类的内部类ExampleFragment中-->
    <fragment
        android:id="@+id/list"
        android:name="com.anfly.app.FragmentLayoutTest$ExampleFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />
</LinearLayout>

2、在activity中动态添加

  • 在Activity的布局文件定义1占位符(FrameLayout)
    这样做的好处是:可动态在Activity中添加不同的 Fragment,更加灵活

activity的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/text">

    <FrameLayout
        android:id="@+id/about_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

设置fragment的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/text">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

在activity中动态添加fragment

public class FragmentActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_transaction_test);
        // 步骤1:获取FragmentManager
        FragmentManager fragmentManager = getFragmentManager();
        // 步骤2:获取FragmentTransaction
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        // 步骤3:创建需要添加的Fragment :ExampleFragment
        ExampleFragment fragment = new ExampleFragment();
        // 步骤4:动态添加fragment
        // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.about_fragment_container, fragment);
        fragmentTransaction.commit();
    }
}

四、在activity中切换fragment保存fragment的状态

All subclasses of Fragment must include a public empty constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it.  

所有fragment的子类必须包含一个公共的空的构造器,以便fragment能在需要的时候还原原来的状态。通俗的说就是:SDK还原fragment数据的时候,肯定先通过调用XXX.newInstance()方法,获取到fragment的实例对象。这就是为什么要提供一个公开的构造方法的原因了!!

fragment使用时常遇到的情况是,在一个activity中切换不同的fragment,通常是需要保存fragment的状态的,返回时你编辑的信息应该要保存的,而不是再次初始化。这时fragment的hide/show方法就派上用场了!

切换不同的fragment,他的生命周期怎么不走了?onPause方法怎么不调用了?onResume怎么只调用一次了?
这时此时方法onHiddenChanged派上用场了,当fragment隐藏时,该方法会调用传入参数为true表示该fragment被隐藏了,当fragment调用了show方法后,该方法传入的参数为false,表示该fragment正在显示!

所以总结起来,如果使用hide/show方法来控制fragment的使用时,原本需要在onResume以及onPause方法做的事情就可以迁移到onHiddenChanged时进行管理,如:

@Override
public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {// 不在最前端界面显示  
                AA.onPause();  
            } else {// 重新显示到最前端中  
                BB.onResume();        
            } 
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值