Android基础之Fragment与Activity交互详解

今天继续讲解Fragment组件的特性,主要是跟Activity的交互和生命周期的关系,我们前面已经说过Fragment是依赖于Activity的,而且生命周期也跟Activity绑定一起。下面我们看看Fragment跟Activity的关系。

1、为Activity创建事件回调方法
在一些情况下, 你可能需要一个fragment与activity分享事件。 一个好的方法是在fragment中定义一个回调的interface, 并要求宿主activity实现它。当activity通过interface接收到一个回调, 必要时它可以和在layout中的其他fragment分享信息。例如, 如果一个新的应用在activity中有2个fragment – 一个用来显示文章列表(framgent A), 另一个显示文章内容(fragment B) – 然后 framgent A必须告诉activity何时一个list item被选中,然后它可以告诉fragmentB去显示文章。

在这个例子中, OnArticleSelectedListener 接口在fragment A中声明:


代码如下:

public static class FragmentA extends ListFragment
{
    //...
    // Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);
    }
    //...
}

然后fragment的宿主activity实现 OnArticleSelectedListener 接口,并覆写 onArticleSelected() 来通知fragment B,从fragment A到来的事件。为了确保宿主activity实现这个接口, fragment A的 onAttach() 回调方法(当添加fragment到activity时由系统调用) 通过将作为参数传入onAttach()的Activity做类型转换来实例化一个OnArticleSelectedListener实例。


代码如下:

public static class FragmentA extends ListFragment
{
    OnArticleSelectedListener mListener;
    //...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
         } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implementOnArticleSelectedListener");
        }
    }
    //...
}

如果activity没有实现接口,fragment会抛出 ClassCastException 异常。正常情形下,mListener成员会保持一个到activity的OnArticleSelectedListener实现的引用,因此fragment A可以通过调用在OnArticleSelectedListener接口中定义的方法分享事件给activity。例如,如果fragment A是一个 ListFragment的子类, 每次用户点击一个列表项,系统调用在fragment中的onListItemClick(),然后后者调用 onArticleSelected() 来分配事件给activity。


代码如下:

public static class FragmentA extends ListFragment
{
    OnArticleSelectedListener mListener;
    //...
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Append the clicked item's row ID with the content provider Uri
         Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
        // Send the event and Uri to the host activity
       mListener.onArticleSelected(noteUri);
    //...
}

传给 onListItemClick() 的 id 参数是被点击的项的行ID,activity(或其他fragment)用来从应用的 ContentProvider 获取文章。

2、添加项目到ActionBar
你的fragment可以通过实现 onCreateOptionMenu() 提供菜单项给activity的选项菜单(以此类推, Action Bar也一样)。为了使这个方法接收调用,无论如何,你必须在 onCreate() 期间调用 setHasOptionsMenu() 来指出fragment愿意添加item到选项菜单(否则, fragment将接收不到对 onCreateOptionsMenu()的调用)。

随后从fragment添加到Option菜单的任何项,都会被追加到现有菜单项的后面。当一个菜单项被选择,fragment也会接收到 对 onOptionsItemSelected() 的回调。也可以在你的fragment layout中通过调用registerForContextMenu() 注册一个view来提供一个环境菜单。当用户打开环境菜单,fragment接收到一个对 onCreateContextMenu() 的调用.当用户选择一个项目, fragment接收到一个对onContextItemSelected() 的调用。

注意: 尽管你的fragment会接收到它所添加的每一个菜单项被选择后的回调,但实际上当用户选择一个菜单项时,activity会首先接收到对应的回调。如果activity的on-item-selected回调函数实现并没有处理被选中的项目,然后事件才会被传递到fragment的回调。

这个规则适用于选项菜单和环境菜单。

3、处理fragment的生命周期
管理fragment的生命周期, 大多数地方和管理activity生命周期很像.和activity一样, fragment可以处于3种状态:
   Resumed
        在运行中的activity中fragment可见。
   Paused
        另一个activity处于前台并拥有焦点,但是这个fragment所在的activity仍然可见(前台activity局部透明或者没有覆盖整个屏幕)。
   Stopped
        要么是宿主activity已经被停止, 要么是fragment从activity被移除但被添加到后台堆栈中。
        停止状态的fragment仍然活着(所有状态和成员信息被系统保持着)。然而,它对用户不再可见,并且如果activity被干掉,他也会被干掉。
其对应关系图如下:

和activity一样, 你可以使用Bundle保持fragment的状态,万一activity的进程被干掉,并且当activity被重新创建的时候, 你需要恢复fragment的状态时就可以用到. 你可以在fragment的 onSaveInstanceState() 期间保存状态,并可以在 onCreate(),onCreateView() 或 onActivityCreated() 期间恢复它。

生命周期方面activity和fragment之间最重要的区别是各自如何在它的后台堆栈中储存。 在默认情况下,activity在停止后,它会被放到一个由系统管理的用于保存activity的后台堆栈。(因此用户可以使用BACK按键导航回退到它)。

然而,仅当你在一个事务期间移除fragment时,显式调用addToBackStack()请求保存实例时,才被放到一个由宿主activity管理的后台堆栈。

另外,管理fragment的生命周期和管理activity生命周期非常类似。因此, "managing the activitylifecycle"中的相同实践也同样适用于fragment。你需要理解的是,activity的生命如何影响fragment的生命。

4、与activity生命周期的协调工作
fragment所生存的activity的生命周期,直接影响fragment的生命周期,每一个activity的生命周期的回调行为都会引起每一个fragment中类似的回调。

例如,当activity接收到onPause()时,activity中的每一个fragment都会接收到onPause()。

Fragment 有一些额外的生命周期回调方法,那些是处理与activity的唯一的交互,为了执行例如创建和销毁fragment的UI的动作。这些额外的回调方法是:

•onAttach()
当fragment被绑定到activity时被调用(Activity会被传入)
•onCreateView()
创建和fragment关联的view hierarchy时调用
•onActivityCreated()
当activity的onCreate()方法返回时被调用
•onDestroyView()
当和fragment关联的view hierarchy正在被移除时调用
•onDetach()
当fragment从activity解除关联时被调用
fragment生命周期的流程,以及宿主activity对它的影响,在图3中显示。在这个图中,可以看到activity依次的每个状态是如何决定fragment可能接收到的回调方法。例如,当activity接收到它的onCreate(),activity中的fragment接收到最多是onActivityCreated()。
一旦activity到达了resumed状态,你可以自由地在activity添加和移除fragment。因此,仅当activity处于resumed状态时, fragment的生命周期才可以独立变化。
无论如何,当activity离开resumed状态,fragment再次被activity的推入它自己的生命周期过程。

5、总结
Fragment的相关知识暂时就讲到这里,例子Demo可以直接看APIDEMO里面的程序,如果不知道API Demo在哪里,请百度!学编程需要自己学会找答案。

(0)

相关推荐

  • Android中Fragment多层嵌套时onActivityResult无法正确回调问题的解决方法

    前言: Fragment也可以使用startActivityForResult方法去打开一个Activity,然后在其onActivityResult方法中处理结果,可是当Fragment嵌套的时候,由于FragmentActivity的BUG导致只会回调最外那层Fragment的onActivityResult方法,于是乎当前Fragment就收不到结果了. BUG分析: 解决这个问题之前我们先通过源码分析一下是什么原因导致的,以22.2.1版本的support-v4库为例 我们先从Fragm

  • Android Activity与Fragment之间的跳转实例详解

    Activity及Fragment之间的跳转 直接跳转 基本使用方法 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void jump(Vie

  • Android Activity与Fragment实现底部导航器

    单Activity多Fragment实现底部导航器 最近由于Android基础知识讲解需要,采用单Activity多Fragment实现类似QQ底部导航器示例,这种开发模式广泛应用于App开发,比如QQ,微信,新浪等,关于Android底部导航栏的实现方式特别多,实现也是五花八门,同时Google在自己推出的Material design中也增加了Bottom Navigation导航控制,实现起来更加简单,且支持动态效果更加酷炫,但是因为是基础的知识,所以打算通过自定义来实现,不使用Botto

  • Android开发 Activity和Fragment详解

    1.Activity的生命周期 1)多个Activity组成Activity栈,当前活动位于栈顶.我们先来看看各种Activity基类的类图: 当Activity类定义出来之后,这个Activity何时被实例化.它所包含的方法何时被调用,这些都不是由开发者所决定的,都应该由Android系统来决定. 下面我们来看一下Activity的生命周期: 2.Activity的用法 1)启动.关闭Activity // 首先需要创建启动的Activity对应的Intent Intent intent =

  • Android应用开发中Fragment与Activity间通信示例讲解

    首先,如果你想在android3.0及以下版本使用fragment,你必须引用android-support-v4.jar这个包 然后你写的activity不能再继承自Activity类了,而是要继承android.support.v4.app.FragmentActivity,一些其他的父类也有相应的变化. 由于在android的实现机制中fragment和activity会被分别实例化为两个不相干的对象,他们之间的联系由activity的一个成员对象fragmentmanager来维护.fr

  • Android中Fragment与Activity的生命周期对比

    Fragment必须是依存于Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期.官网这张图很好的说明了俩者的关系: 可以看到Fragment比Activity多了几个额外的生命周期回调函数: onAttach(Activity); //当Activity与Fragment发生关联时调用 onCreateView(LayoutInflater,ViewGroup,Bundle); //创建该Fragment的视图 onActivityCreate(bun

  • Android 管理Activity中的fragments

    FragmentManager 为了管理Activity中的fragments,需要使用FragmentManager. 为了得到它,需要调用Activity中的getFragmentManager()方法. 因为FragmentManager的API是在Android 3.0,也即API level 11开始引入的,所以对于之前的版本,需要使用support library中的FragmentActivity,并且使用getSupportFragmentManager()方法. 用Fragme

  • Android PreferenceActivity与PreferenceFragment详解及简单实例

    Android  PreferenceActivity与PreferenceFragment 前言 转来转去又回到了Android,闲话少说,这里是参考Android原生的Settings应用来介绍一下PreferenceActivity.PreferenceFragment和headers的使用. PreferenceActivity 我们先通过一个简单的例子来学习一下PreferenceActivity的使用. preferences_scenario_1.xml 我们先通过xml文件来定义

  • Android 中Fragment与Activity通讯的详解

    Android 中Fragment与Activity通讯的详解 与activity通讯 尽管fragment的实现是独立于activity的,可以被用于多个activity,但是每个activity所包含的是同一个fragment的不同的实例. Fragment可以调用getActivity()方法很容易的得到它所在的activity的对象,然后就可以查找activity中的控件们(findViewById()). 例如: ViewlistView =getActivity().findView

  • Android Fragment与Activity之间的相互通信实例代码

    Android Fragment与Activity之间的相互通信 前言 自从Android3.0引入Fragment之后,主要是为了支持动态灵活的界面设计和屏幕的适配问题.Fragmenty不能单独存在,必须依赖Activity作为视图展示的一部分,同事它具有自己的生命周期,接收它自己的事件,具有更加灵活的特性,如今Fragment已经被广泛的应用到App开发中,最常见的就是单Activity多Fragment的模式.Fragment依赖于Activity而存在,就不可避免需要与Activity

  • Android中fragment与activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<详解Android中Fragment的两种创建方式>,就如何创建Fragment混合布局做了详细的分析,今天就来详细说道说道Fragment与宿主Activity之间是如何实现数据交互的. 我们可以这样理解,宿主Activity中的Fragment之间要实现信息交互,就必须通过宿主Activity,Fragment之间是不可能直接实现信息交互的. Fragmen

随机推荐