Fragment(基础的用法,不涉及到Fragment原理)

Fragment的优点:有生命周期的概念、可以作为View使用

生命周期、使用方式、hide、show、attach、detach、remove、add、replace作用:

我们可以把Fragment当成Activity界面的一个组成部分,甚至Activity的界面可以完全由不同的Fragment组成,而且Fragment拥有自己的生命周期并能进行事件处理,这样就不必在Activity中写一堆事件处理逻辑了,更为重要的是,你可以动态的添加、替换和移除某个Fragment

静态的使用Fragment:

这是使用Fragment最简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中:继承Fragment,重写onCreateView决定Fragment的布局、在布局文件中使用Fragment

动态的使用Fragment:

FragmentManager fm = getFragmentManager(); //Fragment里面需要调用getChildFragmentManager

FragmentTransaction transaction = fm.beginTransaction();

transaction.commit();

Fragment家族常用API

android.app.Fragment 主要用于定义Fragment

android.app.FragmentManager 主要用于在Activity中操作Fragment

android.app.FragmentTransaction 保证一些列Fragment操作的原子性

FragmentTransaction方法

开启事务:FragmentTransaction transaction = fm.beginTransatcion();

添加Fragment:transaction.add()

移除Fragment:transaction.remove()

替换Fragment,实际上就是remove()然后add():transaction.replace()

隐藏Fragment,仅仅是设为不可见,并不会销毁:transaction.hide()

显示之前隐藏的Fragment:transaction.show()

销毁view视图 ,和remove()不同,此时fragment的状态依然由FragmentManager维护:detach()

重建view视图,附加到UI上并显示:attach()

提交一个事务:transatcion.commit()

switch(msg.what) {
    case1:
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.framelayout,blankFragmentOne);
        fragmentTransaction.commit();
        break;
    case 2:
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.detach(blankFragmentOne);
        fragmentTransaction.commit();
        break;
    case 3:
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.attach(blankFragmentOne);
        fragmentTransaction.commit();
        break;
}

  1. 09-13 09:46:12.489 26270-26270/com.example.wangzihan.myapplication E/parachute: onAttach 1
  2. 09-13 09:46:12.489 26270-26270/com.example.wangzihan.myapplication E/parachute: onCreate 1
  3. 09-13 09:46:12.490 26270-26270/com.example.wangzihan.myapplication E/parachute: onCreateView 1
  4. 09-13 09:46:12.515 26270-26270/com.example.wangzihan.myapplication E/parachute: onActivityCreated 1
  5. 09-13 09:46:12.515 26270-26270/com.example.wangzihan.myapplication E/parachute: onStart 1
  6. 09-13 09:46:12.515 26270-26270/com.example.wangzihan.myapplication E/parachute: onResume 1
  1. 09-13 09:46:14.488 26270-26270/com.example.wangzihan.myapplication E/parachute: onPause 1
  2. 09-13 09:46:14.489 26270-26270/com.example.wangzihan.myapplication E/parachute: onStop 1
  3. 09-13 09:46:14.490 26270-26270/com.example.wangzihan.myapplication E/parachute: onDestroyView 1
  4.  
  5. 09-13 09:46:16.490 26270-26270/com.example.wangzihan.myapplication E/parachute: onCreateView 1
  6. 09-13 09:46:16.495 26270-26270/com.example.wangzihan.myapplication E/parachute: onActivityCreated 1
  7. 09-13 09:46:16.496 26270-26270/com.example.wangzihan.myapplication E/parachute: onStart 1
  8. 09-13 09:46:16.496 26270-26270/com.example.wangzihan.myapplication E/parachute: onResume 1

switch(msg.what) {
    case1:
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.framelayout,blankFragmentOne);
        fragmentTransaction.commit();
        break;
    case 2:
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.remove(blankFragmentOne);
        fragmentTransaction.commit();
        break;
    case 3:
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.framelayout,blankFragmentOne);
        fragmentTransaction.commit();
        break;
}

  1. 09-13 09:48:35.027 28354-28354/com.example.wangzihan.myapplication E/parachute: onAttach 1
  2. 09-13 09:48:35.027 28354-28354/com.example.wangzihan.myapplication E/parachute: onCreate 1
  3. 09-13 09:48:35.028 28354-28354/com.example.wangzihan.myapplication E/parachute: onCreateView 1
  4. 09-13 09:48:35.035 28354-28354/com.example.wangzihan.myapplication E/parachute: onActivityCreated 1
  5. 09-13 09:48:35.035 28354-28354/com.example.wangzihan.myapplication E/parachute: onStart 1
  6. 09-13 09:48:35.035 28354-28354/com.example.wangzihan.myapplication E/parachute: onResume 1

 

  1. 09-13 09:48:37.027 28354-28354/com.example.wangzihan.myapplication E/parachute: onPause 1
  2. 09-13 09:48:37.027 28354-28354/com.example.wangzihan.myapplication E/parachute: onStop 1
  3. 09-13 09:48:37.028 28354-28354/com.example.wangzihan.myapplication E/parachute: onDestroyView 1
  4. 09-13 09:48:37.030 28354-28354/com.example.wangzihan.myapplication E/parachute: onDestroy 1
  5. 09-13 09:48:37.031 28354-28354/com.example.wangzihan.myapplication E/parachute: onDetach 1

 

  1. 09-13 09:48:39.028 28354-28354/com.example.wangzihan.myapplication E/parachute: onAttach 1
  2. 09-13 09:48:39.028 28354-28354/com.example.wangzihan.myapplication E/parachute: onCreate 1
  3. 09-13 09:48:39.028 28354-28354/com.example.wangzihan.myapplication E/parachute: onCreateView 1
  4. 09-13 09:48:39.040 28354-28354/com.example.wangzihan.myapplication E/parachute: onActivityCreated 1
  5. 09-13 09:48:39.040 28354-28354/com.example.wangzihan.myapplication E/parachute: onStart 1
  6. 09-13 09:48:39.040 28354-28354/com.example.wangzihan.myapplication E/parachute: onResume 1

hide和show只会出发onHiddenChanged回调

FragmentTransaction.addToBackStack(String),把Transaction添加到回退栈,这样按返回键时,会执行popBackStack将Transaction从回退栈中移除,并执行Transaction的反向操作,另外,加到回退栈中的remove只是只是执行了detach操作,不会执行onDestory和onDetach

Fragment与Activity通信

因为所有的Fragment都是依附于Activity的,所以通信起来并不复杂,大概归纳为:

a、如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法

b、如果Activity中未保存任何Fragment的引用,每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作

c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作

<fragment
    android:id="@+id/aaa"
    android:tag="bbb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:name="cn.example.bjwangzihan.myapplication.MyFragment"/>
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment1);
fragmentTransaction.commit();
FragmentTransaction fragmentTransaction2 = fragmentManager.beginTransaction();
fragmentTransaction2.add(fragment1,"bbb");
fragmentTransaction2.commit();

add的时候需要附带TAG信息,XML文件中可以声明id和tag信息

Fragment注意事项(主要涉及到销毁重建的场景):

fragment的获取一定要通过FragmentManager,可以用findFragmentWithTag或者getFragments来得到特定或者所有fragment,如果没有获取到fragment实例再去创建,否则销毁重建的情况下调用getContext时会报mHost空指针异常

如果是通过ViewPager来间接控制Fragment更要注意,传给FragmentPagerAdapter的Fragment实例一定要和FragmentManager中的一致,如果FragmentManager中没有再去创建

Fragment的子类的构造函数务必要保证有无参构造函数,否则在restore时出现"androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment : could not find Fragment constructor",具体参考下面的Fragment实例化源码:

Fragment传参的正确姿势:

Bundle args = new Bundle();
args.putInt("index", index);//把参数放在Bundle
f.setArguments(args);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章