MVPArms 系列 -- Fragment 的正确使用

MVPArms 系列 -- Fragment 的正确使用,第1张

使用 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 实现了 ApplicationActivityLifecycleCallbacks 接口,内部类 FragmentLifecycle 实现了 FragmentManagerFragmentLifecycleCallbacks 抽象类;

并将 ActivityLifecycle 注入到 BaseApplication 中,注入过程是通过 AppDelegate 来代理 Application 的生命周期完成的。

为此作者还专门通过 一篇文章 介绍思想,收获颇多。

ApplicationActivityLifecycleCallbacks 接口定义如下:

FragmentManagerFragmentLifecycleCallbacks 抽象类定义如下:

MainActivity 有三个 Fragment,分别是 HomeFragment DashboardFragment NotificationsFragment

MainActivity 控制 Fragment 的切换,其中 HomeFragment 是主页。

使用 ARouter 控制 Fragment 的切换。

设置 MainActivity 的启动模式为 singleTask ,在 AndroidManifestxml 中为 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 ,您可以通过以下平台找到我:

不能在onCreate函数中获取控件,以为fragment还没有start,你可以在onStart函数中获取:

@Override

protected void onStart() {

superonStart();

View view = thisfindViewById(RidbtnTest);

viewsetOnClickListener(new androidviewViewOnClickListener(){

public void onClick(androidviewView v) {

//TODO

}

});

}

我之前也遇到这样的问题。

Fragment中如何获取listview我的FileFragment继承了Fragment,现在我想要在FileFragment中获取获取filexml

Fragment中如何获取listview

我的FileFragment继承了Fragment,现在我想要在FileFragment中获取获取filexml中的一个listview,我用了下面两种方式:

//fileListView=(ListView)getActivity()findViewById(Ridfile_list);得到空指针

fileListView=(ListView)inflaterinflate(Ridfile_list, null);找不到资源

请指教在Fragment中如何获取listview。

[解决办法]

View rootView = inflaterinflate(Rlayoutfile, null); //先解析filexml布局,得到一个view

ListView listView = (ListView) rootViewfindViewById(Ridfile_list);

1、通过intent将值传给即将跳转的activity

或者通过bundle

2、通过startActivityForResult的跳转方式将值传给跳转前的activity

在下面回调中获取传过来的值

在fragment1中通过getSupportFragmentManager()findFragmentByTag()获取fragment2的对象,调用fragment2中的方法将值传过去

Fragment1

Activity中创建fragment,并给fragment指定tag

Fragment2

1、通过setArguments传递bundle,通过getArguments获取bundle

activity

2、通过fragment中的attach()生命周期,将context转为Mainactivity,然后调用MainActivity中的方法

通过在fragment中实现接口的方式,Fragment向Activity传值的步骤 接口回调传递(5部曲)

1fragment中准备回调接口 接口中声明传值的回调方法

2在fragment中定义属性private MyListener myListener

3重写fragment中的onAttach()方法:listener = (MyLisener)getActivity();

4fragment触发事件时回传值

5Activity中实现回调接口 重写回调方法获取回传的值并显示

在MainActivity中:

(待完成)

重新整理一遍。

以前的Fragment传输数据都很熟悉,获取fragment实例,arguments,回调,eventbus等,方式的确多样化。

以前大多数传递都需要 持有实例,这是很危险 的。

但是谷哥已经推新,推荐使用新的api去传递数据,在版本130-alpha04 中新增了result api去 *** 作。

新api中通过注册监听等方式来进行交互,耦合度低。

result api 同时也包含 startActivityForResult 等api,之前有过一篇文章 Result Api registerForActivityResult 。

假如你要在两个 fragment之间传递 ,需要用到两个api,一个发送,一个接收。

这里做一个测试,首先启动一个SplashFragment,在启动页结束的时候发送一条数据过去HomeFragment。

添加引用:

这样一看一目了然,两个方法可以直接使用,api点进去可以看到 源码

发现是 parentFragmentManager 中的方法只是kotlin 简化 了而已。

上面是两个 同级Fragment 的传递方式。

现在换个场景,Fragment是子集的时候,监听就不一样了。

这里新建一个TabFragment,然后TabFragment里面有两个子tab,现在 子tab要传递数据到TabFragment中

这里不是直接用parentFragmentManager了,需要用 childFragmentManager 去注册了,不然会失效。

然后发送还是一样,这里在子tab里显示一个textview,点击textview的时候发送一条数据过来。

运行一波:

在换一个场景。

如果从TabFragment中传递数据到子tab中, 子tab去接收

这里为了方便测试,在TabFragment中添加一个悬浮按钮,点击按钮传递数据到子tab中。

这种方式不持有对方引用,避免了很多未知的问题,自带生命周期的监听,会在销毁的同时移除监听。

从 Fragment->Fragment;子Fragment->Fragment;Fragment->子Fragment ;

通过新的Result Api,分别对三个不同场景测试,梳理了使用流程。

从startActivityForResult到Fragment,发现新式解耦法基本都是通过注册监听等方式来实现;同时绑定生命周期,这一整套也可以自己封装在平时的一些工具类上,避免重耦合。

以上就是关于MVPArms 系列 -- Fragment 的正确使用全部的内容,包括:MVPArms 系列 -- Fragment 的正确使用、如何获取fragment里的控件、如何在fragment中获取view等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9289654.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存