西安电子科技大学机电工程学院 郭雨佳 韩雨辰 赵明英 朱俊杰
在现有智能手机操作系统中,Android占绝对主导地位。Activity是Android四大组件之一,Fragment是一种嵌套在Activity中的UI组件。由于多个Activity的进栈出栈会造成程序卡顿,所以实际开发的时候,为了达到更好的用户体验大多会使用Fragment来设计用户交互界面。正因如此,Activity和Fragment之间的通信便显得尤为重要。本文分析了两者间的多种通信方式,提出接口回调方式是进行通信的最佳方式。
在Android程序设计中,Activity是重要的控件之一。一个Activity就代表了应用程序中的一个页面。每次点击页面进行跳转的时候,需要将当前的Activity的状态保存至堆栈,下次使用的时候再从堆栈中取出来展示给用户。这样不断的进出堆栈,将会导致应用程序运行过程中出现卡顿,严重影响用户体验。为了解决这一问题,Android系统引入了Fragment。Fragment并不是一个独立的部分,是一种可以嵌入到Activity中的UI控件。Fragment的出现使在同一个Activity上进行界面的切换成为现实。
创建Fragment的方法有动态和静态两种。前者就是通过Java代码来创建Fragment的实例,后者则是在编写Activity的xml布局文件时通过<fragment>标签实现控件的创建。
动态创建的具体步骤:
第一步:在当前Activity的布局文件中创建FrameLayout并为其设置id;
第二步:鼠标移动到当前包名处并单击右键,选择new->Fragment->Blank Fragment,创建新的Fragment;
第三步:在Activity的onCreat()方法中使用代码将fragment添加到FrameLayout。
静态创建的具体步骤:
第一步:鼠标移动到当前包名并单击右键,选择new->Fragment->Blank Fragment,创建新的Fragment;
第二步:在在xml文件中创建fragment控件,并通过name属性引入fragment文件,同时可以为fragment创建一个id,以便后续的使用。
由于Fragment是嵌入到Activity中的一种控件,所以它不会单独存在,它必须附着到Activity中。基于此,Fragment的生命周期会受到Activity生命周期的影响。Fragment和Activity有着相似的生命周期,它会随着Activity的暂停而暂停,随着Activity的销毁而销毁。我们就可以对附着在Activity上面的Fragment进行操作的前提是这个Activity是处于正常运行中的。常见的操作有添加、替换和删除等。Fragment的生命周期如图1所示。
图1 Fragment的生命周期示意图
通过调用getSupportFragmentManager()函数可以拿到用来操作Fragment的Manager,然后通过它的findFragmentByTag()或者findFragmentById()拿到我们需要通信的Fragment实例(如果Fragment是直接在XML中定义的,那么就使用findFragmentById()拿到Fragment),然后就可以对拿到的Fragment进行各种操作了。
我们可以通过getActivity().findViewById()的方法获取Fragment附着的Activity中的控件,但是这种方式代码耦合性太强,不利于代码的移植和优化,所以更多情况下采用回调方法来进行二者的通信。在Fragment中声明一个接口并提供一个接口的引用变量,接口中定义所需的方法,然后让Activity实现此接口并按照需要重写接口中的方法。当Fragment需要访问Activity中数据时,只需要通过接口实例调用接口方法并将参数传递,具体的操作代码则在Activity中的接口方法中完成。
由于Fragment是依附于Activity的,所以Fragment之间通信不能直接通信,必须依靠所依附的Activity。为了降低代码之间的耦合,可以通过回调实现Fragment之间通信。
任意Fragment之间要想通信必须通过他们所属的Activity来完成,不能是多个Fragment之间的直接通信、调用。同理,Fragment要访问它所附着的Activity中的信息也得在Activity中进行。Fragment与其所附着的Activtiy之间通信的最佳方式应该是:
在发起事件的Fragment中定义一个接口,接口中声明你的方法;
在onAttach()方法中要求Activity实现接口;
在Activity中实现该接口并重写该方法。