效果
FragmentController介绍
FragmentController用于控制fragment,它把activity的许多事件分发给fragment处理。更准确的说法是分配给fragment manager,然后由fragment manager分发给fragment。FragmentController通常都是在activity中创建的,并且activity作为FragmentController的host存在。
FragmentHostCallback介绍
在创建FragmentController的时候,我们需要指定一个FragmentHostCallback实例用于指定FragmentController的宿主。FragmentHostCallback定义了许多宿主依赖行为:
- 宿主实例回调onGetHost(),返回宿主实例。
- 查找容器的回调onFindViewById(id: Int),返回fragment添加容器。
- 生成LayoutInflater的回调onGetLayoutInflater(),返回用于实例化fragment布局的LayoutInflater
private val mFragments =
FragmentController.createController(object : FragmentHostCallback<Service>(
this,
Handler(Looper.getMainLooper()),
0
) {
override fun onGetHost(): Service? {
return this@FloatWindowService
}
override fun onFindViewById(id: Int): View? {
return rootContainer.findViewById(id)//rootContainer已经被添加到WindowManager管理
}
override fun onGetLayoutInflater(): LayoutInflater {
return super.onGetLayoutInflater().cloneInContext(this@FloatWindowService)
}
})
通过service管理浮窗
app显示浮窗的功能通常要求应用退出的时候也能正常显示,所以我们需要启动service来管理浮窗。service没有画面描绘的权利,我们需要结合window manager来添加浮窗界面显示。关于window manager添加View的权限申请问题,有大量的文章都有介绍。这里他不是讨论的重点。如果浮窗的业务逻辑不是很复杂,并且没有过多的ui状态转换,那么我们可以简单地在service中控制浮窗ui的切换。如果浮窗的逻辑复杂,ui状态转换频繁且有许多ui状态需要维护。这种情况下,service管理ui状态就力不从心。所以本篇文章想利用fragment来管理ui状态。
如何将FragmentController与service绑定并管理浮窗状态
根据前面的介绍,我们已经掌握了创建FragmentController的方法。接下来我们把service的状态分发给FragmentController。当service被创建的时候,我们把FragmentController的状态切换到resume状态。当service被销毁的时候,我们把FragmentController的状态切换到destroy状态。
override fun onCreate() {
super.onCreate()
windowManager.addView(rootContainer, layoutParameter)
mFragments.attachHost(null)//没有parent fragment,所以是null参数。
mFragments.dispatchResume()
}
override fun onDestroy() {
super.onDestroy()
mFragments.dispatchDestroy()
windowManager.removeView(rootContainer)
}
fragment使用时需要注意的问题
- 由于FragmentController是从Service中创建的,所以Fragment中获取不到activity实例。
- 由于获取不到activity实例,所以启动activity时使用的Context都是Service类型的或是Application类型的。我们都知道Service 或Application类型的Context启动activity的时候都需要添加Intent.FLAG_ACTIVITY_NEW_TASK flag。
Git
https://github.com/mjlong123123/TestFloaWindow.git
我的公众号已经开通,公众号会同步发布。
欢迎关注我的公众号