Fragment

FragmentManager

  • FragmentManager类具体管理的是:
    • fragment 队列
    • fragment事务回退栈

FragmentManager

在事务提交之前可以将事务保存由Activity管理的后台栈中,并允许用户导航返回
transaction.replace(R.id.fragment_container,newFragment);
transaction.addToBackStack(null);
transaction.commit();

Fragment的生命周期

Fragment的状态

  • 运行状态。可见,且关联的Activity处于运行状态。
  • 暂停状态。活动处于暂停状态时,相关联的可见fragment处于暂停状态。
  • 停止状态。活动处于停止状态时,相关联的fragment处于停止状态。或者通过 FragmentTransaction的replace、remove将其从活动中移除,且提交前调用addToBackStack()方法就会处于暂停状态。
  • 销毁状态。活动销毁相关联的fragment就会跟着销毁。或者通过 FragmentTransaction的replace、remove将其从活动中移除,且提交前没有调用addToBackStack()方法就会处于销毁状态。

回调方法

  • 除了拥有Activity的回调方法外,还有额外以下几个回调方法。
    • onAttach().当fragment和活动建立时调用。
    • onCreateView().为fragment创建视图时调用。
    • onActivityCreated().确保与fragment相关联的活动一定已经创建完毕的时候调用。
    • onDetach().当fragment与活动解除关联的时候调用。

      来自官网的图


Fragment的生命周期

Fragment的托管方式

静态方法

Activity的布局
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res.android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_patent"
        android:layout_weight="1"/>
    <fragment
        android:id="@+id/right_fragment"
        android:name="com.example.fragmenttest.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_patent"
        android:layout_weight="1"/>
</LinearLayout>
fragment的布局
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res.android"
android:layout_width="match_parent"
android:layout_height="match_parent">
    <Textview
        ..../>
</LinearLayout>
fragment.java
public class LeftFragment extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
        View view=inflater.inflate(R.layout.left_fragment,container,false);
        return view;
    }
}
RightFragment 类似

动态方法

这种方式比较复杂,但也是唯一可以在运行时控制fragment的方式。我们自行决定何时添加fragment以及随后可以完成何种具体任务;也可以移除fragment,用其他fragment代替当前fragment,然后重新添加已移除的fragment。

封装一个Activity,继承它,在抽象方法中返回要添加的fragment

public abstract class SingleFragmentActivity extends AppCompatActivity {
    protected  abstract Fragment createFragment();

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //将FrameLayout 容器视图装载为视图
        setContentView(R.layout.activity_fragment);
        //获取Fragment管理器
        // FragmentManager管理着fragment队列(事务操作着队列里面的fragement)和回退栈(管理多个事务)
        FragmentManager fm=getSupportFragmentManager();   
         // 向FragmentManager请求并获取fragment。其容器视图的ID=fragment的ID
        Fragment fragment=fm.findFragmentById(R.id.fragment_container);

      /*为什么要获取的fragment会存在于队列中呢?
      设备旋转或回收内存时,Android会销毁Activity,而后重建时,会调用Activity.onCreate(...)方法。activity被销毁时,它的FragmentManager会将fragment队列保存下来。这样,activity重建时,新的FragmentManager会首先获取保存的队列,然后重建fragment队列,从而恢复到原来的状态。*/
        if(fragment==null){
            fragment=createFragment();
            fm.beginTransaction()
                //add(...)方法是整个事务的核心,它含有两个参数: 容器视图资源ID和新创建的fragment
                .add(R.id.fragment_container,fragment)
                .commit();
        /*
            容器视图资源ID的作用有
            1.告诉FragmentManager,fragment视图应该出现在activity视图的什么位置;
            2.用作FragmentManager队列中fragment的唯一标识符。
        */         
        }

    }
}
“@Override protected Fragment createFragment(){ return FragmentTest.newInstance(); } “ “ public static FragmentTest newInstance() { Bundle args = new Bundle(); CrimeListFragment fragment = new CrimeListFragment(); fragment.setArguments(args); return fragment; } “

每个fragment都需要一个唯一的标识符
android:id提供唯一标识符
android:tag提供唯一的字符串
如果以上两个都没有,系统会使用其容器视图的ID

activity_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</FrameLayout>
  • activity间通过fragment返回结果
    在fragment中可以startActivityForResult(Intent,int)和onActivityResult(int,int,Intent)但是没有setResult(int ,intent).
    所以需要借助活动来调用getActivity.setResult();
    通过fragment返回结果
  • fragment间的数据传递
    1. 设置目标fragment
      public void setFragment(fragment,requestCode)
    2. 传递数据给目标fragment
      getTargetFragment().onActivityResult(getTargetRequsetCode,resultCode,intent);
      fragment间数据传递
  • argument
    添加名为newInstance()的静态方法给Fragment类。在里面完成fragment实例的创建并调用Fragment.setArguments(Bundle)方法。
public class MyFragment extends Fragment{
    ......
    public static MyFragment newInstance(data){
        Bundle args=new Bundle();
        args.putSerializable(MY_DATA,data);

        MyFragment fragment=new MyFragment();
        fragment.setArguments(agrs);
        return fragment;
    }
}

获取argument

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    data=getArguments().getSerializable(My_DATA);
}   

存入Bundle的数据必须是可序列化的数据。比如基本类型,实现了Parcellable接口的对象,实现了Serializable接口的对象,以及一些Android 支持的特殊对象。具体查看Bundle类。

为什么要使用fragment argument呢?为什么不直接创建一个实例变量呢?
创建实例变量的方式并不可靠。因为,在操作系统重建fragment时,设备配置发生改变时,
用户暂时离开当前应用时,甚至操作系统按需回收内存时,任何实例变量都不复存在了。尤其是内存不够,操作系统强制杀掉应用的情况,可以说是无人能挡。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值