MVPArms 系列 -- Fragment 的正确使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVPArms 系列 -- Fragment 的正确使用相关的知识,希望对你有一定的参考价值。

参考技术A

使用 MVPArms 开发也有一段时间了,首先感谢 作者 的无私奉献和分享!在此记录一下 Fragment 使用过程中遇到的问题和解决方案。

Activity Fragment 的生命周期如下:
<div align=center>

<div align=center>

</div>

<div align=center>

</div>

MVPArms 框架对 Activity Fragment 的生命周期进行了很好的封装。
通过 ActivityDelegate 代理 Activity 的生命周期(具体实现为 ActivityDelegateImpl ),通过 FragmentDelegate 代理 Fragment 的生命周期(具体实现为 FragmentDelegateImpl );
然后在 ActivityLifecycle 实现了 Application.ActivityLifecycleCallbacks 接口,内部类 FragmentLifecycle 实现了 FragmentManager.FragmentLifecycleCallbacks 抽象类;
并将 ActivityLifecycle 注入到 BaseApplication 中,注入过程是通过 AppDelegate 来代理 Application 的生命周期完成的。
为此作者还专门通过 一篇文章 介绍思想,收获颇多。

Application.ActivityLifecycleCallbacks 接口定义如下:

FragmentManager.FragmentLifecycleCallbacks 抽象类定义如下:

MainActivity 有三个 Fragment,分别是 HomeFragment DashboardFragment NotificationsFragment
MainActivity 控制 Fragment 的切换,其中 HomeFragment 是主页。

使用 ARouter 控制 Fragment 的切换。

设置 MainActivity 的启动模式为 singleTask ,在 AndroidManifest.xml 中为 MainActivity 添加以下属性:

MainActivity 的布局文件包含了一个 FramLayout,用来动态添加 Fragment;还包含了一个 BottomNavigationView,在 Activity 中控制 Fragment 的切换。

MainActivity 中有一个 List 用来存储 Fragment,根据每个 Fragment 在 List 中的索引切换 Fragment。此处的切换方式使用的是 hide/show 的方式,当 Fragment 需要频繁切换的时候,这样做比 replace 的方式更有效率。

每个 Fragment 的布局文件都有两个 Button,用来在一个 Fragment 切换至其他的 Fragment。

具体实现方式是由 ARouter 先跳转到 Activity,然后由 Activity 控制 Fragment 的切换。

在 Fragment 通过 ARouter 跳转到 Activity,会触发 Activity 的 onNewIntent(Intent intent) 方法回调,所以在 onNewIntent 处理ARouter 携带的要切换的目标 Fragment 的索引,然后通过 BottomNavigationView 的 OnNavigationItemSelectedListener 控制切换 Fragment,同时设置 Toolbar 的 Title。从而完成从一个 Fragment 切换至其他的 Fragment。

由于同一个 Activity 与三个 Fragment 的生命周期同步,所以当 Activity 在 onResume 状态下,三个 Fragment 也在同时 onResume,使用 hide/show 的方式切换 Fragment 无法刷新 Fragment 的状态。这时候 onHiddenChanged(boolean hidden) 方法就派上用场了,可以在 Fragment 中重写此方法来处理刷新等逻辑。

当设备旋转或者 Activity 长期处于后台而被系统回收,Activity 的会经历销毁->重建的过程。但是我们可以保存 Fragment,当 Activity 重建时继续使用已经存在的 Fragment 实例,避免浪费系统资源。

利用系统 API 提供的 Fragment#setRetainInstance(boolean retain) 方法来保存 Fragment 实例,在 GlobalConfiguration 的 FragmentLifecycleCallbacks 回调方法里设为 true。

因为 FargmentManager 在 Activity 重建时会自动恢复,所以可以在添加 Fragment 时设置 tag,然后通过 FragmentManager#findFragmentByTag(String tag) 获取 FragmentManager 中已存在的 Fragment 实例。
这里使用了 FragmentUtils 工具类处理 Fragment。

在 Activity 的 onSaveInstanceState(Bundle outState) 保存当前 Fragment 索引:

在 Activity 的 initData(Bundle savedInstanceState) 恢复原来 Fragment 索引:

在 Activity 中持有 各个 Fragment 实例,MVPArms 的 IFragment 接口提供一个 setData(Object data) 方法,可以将通信数据传递给目标 Fragment:

然后在 Fragment 中重写 setData() 方法接收消息,根据消息做一些事情:

使用 ARouter 将 通信数据携带发送给 Activity,然后在 Activity 的 onNewIntent(Intent intent) 接收处理。

Fragment 之间的通信可以通过 Fragment 先与 Activity 通信,然后由 Activity 传递给目标 Fragment。例如上面的通过按钮切换 Fragment 就是一个例子。通过 ARouter 来实现。

Activity 也可以在布局文件里直接使用 <fragment> 标签来静态加载 Fragment。
<fragment> 中的 android:name 属性指定要在布局中实例化的 Fragment 类。
当系统创建此 Activity 布局时,会实例化在布局中指定的每个片段,并为每个片段调用 onCreateView() 方法,以检索每个片段的布局。系统会直接插入片段返回的 View 来替代 <fragment> 元素。
用法如下:

欢迎 star 和 issue:

我是 xiaobailong24 ,您可以通过以下平台找到我:

Fragment全解析系列:Fragment之我的解决方案:Fragmentation

源码地址:Github,欢迎Star,Fork。

Demo网盘下载(V_0.7.13)
Demo演示:
单Activity + 多Fragment,项目中有3个Demo。

流式的单Activity+多Fragment:

技术分享
流式的单Activity+多Fragment

类似微信交互方式的单Activity+多Fragment:(全页面支持滑动返回)

技术分享
类似微信交互方式的单Activity+多Fragment

类似新版仿知乎交互方式的单Activity+多Frgment:

技术分享
类似新版仿知乎交互方式的单Activity+多Frgment

Fragmentation

为"单Activity + 多Fragment的架构","多模块Activity + 多Fragment的架构"而生,帮你简化使用过程,轻松解决各种复杂嵌套等问题,修复了官方Fragment库存在的一些BUG。

技术分享
 

特性

1、有效解决各种复杂嵌套、同级等Fragment重叠问题

2、实时查看Fragment的(包括嵌套Fragment)栈视图的对话框和Log,方便调试

3、增加启动模式、startForResult等类似Activity的方法

4、类似Android事件分发机制的Fragment回退方法:onBackPressedSupport(),轻松为每个Fragment实现Back按键事件

5、完美的防抖动解决方案(防止用户点击速度过快,导致启动多个Fragment)

6、提供可轻松 设定Fragment转场动画 的解决方案

7、修复官方库里pop(tag/id)出栈多个Fragment时的一些BUG

8、支持SwipeBack滑动边缘退出(需要使用Fragmentation_SwipeBack库,详情README)

技术分享
通过logFragmentStackHierarchy(TAG)查看Log

重大更新日志

0.7.X 来了!!!

1、2个新demo: 仿知乎交互 + 仿微信交互的新Demo,展示复杂嵌套Fragment的交互场景

2、全新的Fragment恢复机制

3、更容易编写各种嵌套Fragment的代码

4、支持同级Fragment的处理

5、实验性支持SharedElement-Material过渡动画

6、全新的类似Android事件分发机制的onBackPressedSupport()

如何使用

1. 项目下app的build.gradle中依赖:

// appcompat v7包是必须的
compile ‘me.yokeyword:fragmentation:0.7.12‘
// 如果想使用SwipeBack 滑动边缘退出Fragment/Activity功能,请再添加下面的库
// compile ‘me.yokeyword:fragmentation-swipeback:0.7.9‘

2. Activity继承SupportActivity:

public class MainActivity extends SupportActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(...);
        if (savedInstanceState == null) {
            loadRootFragment(R.id.fl_container, HomeFragment.newInstance());  
        }
    }

3. Fragment继承SupportFragment:

public class HomeFragment extends SupportFragment {

    private void xxx() {
        // 启动新的Fragment, 同时还有start(fragment,SINGTASK)、startForResult、startWithPop等启动方法
        start(DetailFragment.newInstance(HomeBean));
        // ... 其他方法请自行查看 API
    }

进一步使用,查看wiki



文/YoKey(简书作者)
原文链接:http://www.jianshu.com/p/38f7994faa6b
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。











以上是关于MVPArms 系列 -- Fragment 的正确使用的主要内容,如果未能解决你的问题,请参考以下文章

Fragment全解析系列:正确的使用姿势

Fragment全解析系列:那些年踩过的坑

Fragment系列:布局xml中的fragment标签,如何隐藏?

Fragment全解析系列:Fragment之我的解决方案:Fragmentation

Kotlin基础从入门到进阶系列讲解(基础篇)Fragment的基本使用

Kotlin基础从入门到进阶系列讲解(基础篇)Fragment的基本使用