1 Fragment的生命周期

Fragment是依附于Activity而存在的,故而Activity的额生命周期直接影响到Fragment的生命周期。先来看下官网给的生命周期图。

从上面可以看出,Fragment多了以下几个主要方法:

  1. onAttach(Activity):当Fragment与Activity发生关联时调用。
  2. onCreateView(LayoutInflater, ViewGroup,Bundle):创建该Fragment的视图。
  3. onActivityCreated(Bundle):当Activity的onCreate方法返回时调用。
  4. onDestoryView():与onCreateView想对应,当该Fragment的视图被移除时调用。
  5. onDetach():与onAttach相对应,当Fragment与Activity关联被取消时调用。

2 Fragment的使用

1 静态添加

  1. 继承Fragment,重写onCreateView,决定Fragemnt的布局;
  2. 在Activity中声明此Fragment,就当和普通的View一样。使用< fragment>标签添加碎片,android:name属性来显式指明要添加的碎片类名,注意一定要将类的包名也加上。

2 动态添加

  1. 创建待添加的碎片实例。
  2. 获取到FragmentManager,在活动中可以直接调用 getFragmentManager()方法得到。(app包下的fragment,v4包的则使用getSupportFragmentManager,用于支持兼容低版本)
  3. 开启一个事务,通过调用 beginTransaction()方法开启。
  4. 向容器内加入碎片,一般使用 replace()方法实现,需要传入容器的 id 和待添加的碎片实例。
  5. 提交事务,调用 commit()方法来完成。

3 注意点

如果使用Android3.0以下的版本,需要引入v4的包,然后Activity继承FragmentActivity,然后通过 getSupportFragmentManager获得FragmentManager。不过还是建议版Menifest文件的uses-sdk的 minSdkVersion和targetSdkVersion都改为11以上,这样就不必引入v4包了。

3 主要API方法

1 FragmentManage

主要用于在Activity中操作Fragment,获取的方式为:

//app包 getFragmentManager() // v4包中,getSupportFragmentManager

2 FragmentTransaction

保证一些列Fragment操作的原子性,Fragment的事务处理,获取的方式为:

//开启一个事务FragmentTransaction transaction = fm.benginTransatcion();

常用方法有:

//添加transaction.add()//删除。如果没添加到回退栈,则fragment实例销毁transaction.remove()//替换,相当于remove+addtransaction.replace()//隐藏当前的Fragment,仅仅是设为不可见,并不会销毁transaction.hide()//显示之前隐藏的Fragmenttransaction.show()//提交本次事务。一定要在Activity.onSaveInstance()之前调用transatcion.commit()

4 Fragment与Activity的通信

1 获取Fragment实例

Fragment实例的获取因Fragment添加方式不同而不同。

1 静态添加的Fragment

在activity的布局中的< fragment>标签内设置android:id属性,调用 FragmentManagerfindFragmentById()方法+强转获取到Fragment的实例对象。

2 动态添加的Fragment

一种是直接实例化Fragment对象,用实例对象进行后续的操作。
另一种是在add或者replace 的时候添加第三个TAG参数,然后通过调用 FragmentManagerfindFragmentByTag()方法+强转获取Fragment实例对象。此时如果如果需要获取控件上的信息,可以通过 实例.getActivity().findViewById()的形式获取到相关的控件。

2 获取Activity实例

在Fragment中可以通过getActivity()得到当前绑定的Activity的实例,然后进行操作。
需要注意的是,如果在Fragment中需要Context,可以通过调用getActivity() ,如果该Context需要在Activity 被销毁后还存在,则使用 getActivity().getApplicationContext()

5 进阶

1 回退栈的管理

Fragment不像activity一样自带一个任务栈进行管理,它需要人为的进行添加:

FragmentTransaction.addToBackStack(null);

2 屏幕选择避免重新创建Fragment

1 产生原因

因为当屏幕发生旋转,Activity发生重新启动,默认的Activity中的Fragment也会跟着Activity重新创建;这样造成当旋转的时候,本身存在的Fragment会重新启动,然后当执行Activity的onCreate时,又会再次实例化一个新的Fragment,这就是出现该问题的原因。

2 解决方法

通过检查onCreate的参数
Bundle savedInstanceState就可以判断,当前是否发生Activity的重新创建。
代码如下:

//在setContentView后面添加if (savedInstanceState == null){            mFOne=new FragmentOne();            FragmentManager fm = getFragmentManager();            FragmentTransaction tx = fm.beginTransaction();              tx.add(R.id.id_content, mFOne, "ONE");                         tx.commit();           }

上述仅仅只是解决了界面的重绘,那数据又该如何处理呢?
我们知道,在activity中有onSaveInstanceState()可以进行保存数据,Fragment也同样有此方法。
而activity可以在Created中进行数据的恢复,通过前面的生命周期图可以看出,Fragment在onCreate 或者onCreateView 或者onActivityCreated进行恢复都可以进行数据的恢复。

3 单双页自动选择

1 问题的产生

一个APP需要应对不用屏幕大小的设备,在平板上,有时候会包含2个碎片,即双页,而手机屏幕小只有一个碎片,那么如何让APP自动识别呢?

2 解决的方案

在《第一行代码》中,郭神给出了解决的方法:

新建一个layout_large包,并新建双页显示的布局文件(文件名和单页显示的一致)

其中 large 就是一个限定符,那些屏幕被认
为是 large 的设备就会自动加载 layout-large 文件夹下的布局,而小屏幕的设备则还是会加载layout 文件夹下的布局。
下面是Android 中一些常见的限定符参考表。

可是large到底是多large呢?为了更加灵活地为各种设备加载不同的布局,此时就需要最小宽度限定符( Smallest-width Qualifier)。
最小宽度限定符允许我们对屏幕的宽度指定一个最小指(以dp为单位),然后以这个最
小值为临界点,屏幕宽度大于这个值的设备就加载一个布局,屏幕宽度小于这个值的设备就
加载另一个布局。
例如在 res 目录下新建layout-sw600dp文件夹,这样屏幕宽度大于 600dp 的设备上时,会加载 layout-sw600dp中的布局;当程序运行在屏幕宽度小于 600dp 的设备上时,则仍然加载默认的layout中的布局。
需要注意一点,最小宽度限定符是在 Android 3.2 版本引入的,由于这里我们最低兼容
的系统版本是 4.0,所以可以放心地使用它。

4 Fragment与ActionBar和MenuItem集成

Fragment中:
a、在Fragment的onCreate中调用 setHasOptionsMenu(true);

@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setHasOptionsMenu(true);//步骤1}

b、然后在Fragment子类中实现onCreateOptionsMenu

 @Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {    inflater.inflate(R.menu.fragment,menu);//  super.onCreateOptionsMenu(menu, inflater);}

c、如果希望在Fragment中处理MenuItem的点击,也可以实现onOptionsItemSelected;当然了Activity也可以直接处理该MenuItem的点击事件。

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    if(R.id.settings==item.getItemId()){//步骤3,改return true        Toast.makeText(getActivity(), "测试", Toast.LENGTH_SHORT).show();    }    return true;}

Activity中:

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    switch (item.getItemId()) {        case R.id.action_settings: {            Toast.makeText(this, "主页面", Toast.LENGTH_SHORT).show();            return true;        }        default:            //如果希望Fragment自己处理MenuItem点击事件,一定不要忘了调用super.xxx              return super.onOptionsItemSelected(item);    }}

效果图如下所示:

5 没有布局的Fragment的作用

没有布局文件Fragment实际上是为了保存,当Activity重启时,保存大量数据准备的。

更多相关文章

  1. Android(安卓)监听软键盘状态的实例详解
  2. 基于AndroidStudio开发的简单登陆页面制作
  3. Android学习笔记(三)UI
  4. Android(安卓)RelativeLayout布局
  5. AndroidStudio常见问题
  6. AndroidStudio插件:布局文件转化Databinding
  7. Android(安卓)SlidingMenu 布局实现
  8. 【Android】毫无耦合性,一个Item根布局搞定 item侧滑删除菜单,像IO
  9. flutter的AndroidX版本适配

随机推荐

  1. android英语字典(内含源码哦)
  2. android 模拟器启动不了
  3. Android manifest之系统自带的permission
  4. Flutter之原生交互(Android)
  5. Android系列学习:handler,HandlerThread
  6. Android-View的滑动
  7. [Android]ScrollView和ListView套用冲突
  8. 狂刷Android范例之2:剪贴板范例
  9. 转:深入解读Linux与Android的相互关系
  10. Android之用自定义的shape去实现shadow效