Skip to content

局部浮窗

petterp edited this page Aug 30, 2026 · 1 revision

局部浮窗(Scope Host)

局部浮窗把浮窗挂到某个具体容器上:任意 ViewGroup、Activity 的 content、或 Fragment 的根 view。 它不进注册表FloatingX.controls() 里看不到),生命周期归调用方,不再需要时调用 control.cancel()

需要模块 io.github.petterpx:floatingx-scope,见 快速开始

三种入口

入口 挂在哪 注意
Activity.fxScope(tag) {} android.R.id.content 必须在 setContentView() 之后调用;API 29+ 页面 destroy 时自动 cancel
ViewGroup.fxScope(tag) {} 这个 ViewGroup 自己 浮窗只在该容器内活动
Fragment.fxScope(tag) {} Fragment 的根 view onCreate 里就能写,view 就绪后自动挂上;fragment destroy 时自动 cancel(#244)

用法

// Activity:挂在 android.R.id.content 上(必须在 setContentView 之后调用)
val actFx = fxScope("scope-act") {
    layout(R.layout.fx_card)
    anchor(FxGravity.BOTTOM_END)
    persist(FxSpStorage(this@ScopeHostActivity))
}
actFx.show()

// 任意 ViewGroup:浮窗只在这个容器内活动
val boxFx = box.fxScope("scope-box") {
    layout(R.layout.fx_card)
    anchor(FxGravity.TOP_START)
}

// Fragment:在 onCreate 里就能写,view 就绪后自动挂上,fragment destroy 时自动 cancel
class ScopeFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        fxScope("scope-frag") {
            layout(R.layout.fx_card)
            anchor(FxGravity.CENTER)
        }.show()
    }
}

Activity.fxScope 在 API < 29 上没有自动收尾,建议调用方自己在 onDestroycancel() (不 cancel 也不会泄漏:host 只被 Activity 自己的 view 树引用)。

在 install / create 的 DSL 里指定 host

fxScope {} 是便捷写法;也可以在 FloatingX.create(tag) {} / FloatingX.install(tag) {} 的 DSL 里 用 viewGroupHost(viewGroup) / fragmentHost(fragment) 显式指定 host:

val fx = FloatingX.create("scope-dsl") {
    layout(R.layout.fx_card)
    anchor(FxGravity.TOP_END)
    viewGroupHost(container)          // 或 fragmentHost(fragment)
}
fx.show()

FloatingX.create 不进注册表,FloatingX.install 才注册;局部浮窗一般用 create

显示在 Dialog 之上

Dialog 有自己的 Window,层级在 Activity 之上,挂在 Activity 上的浮窗盖不住它。 把浮窗直接挂到 Dialog 的 decorView 上(decorView 必须在 dialog.show() 之后取):

dialog.show()
val decor = dialog.window?.decorView as? ViewGroup ?: return
val dialogFx = FloatingX.create("dialog") {
    layout(R.layout.fx_card)
    anchor(FxGravity.TOP_END)
    viewGroupHost(decor)
}
dialogFx.show()
dialog.setOnDismissListener { if (dialogFx.state != FxState.CANCELLED) dialogFx.cancel() }

更多同类问题见 常见问题

Java

Java 侧没有 DSL,用 ViewGroupHost.of(...) + FloatingX.create(...)

ViewGroup content = activity.findViewById(android.R.id.content);
FxControl control = FloatingX.create(config, ViewGroupHost.of(content), "java-scope");
control.show();

tag 的作用

局部浮窗的 tag 只用于日志与位置持久化的存储键,留空则不持久化。 它不参与注册表,所以不同页面里用同一个 tag 也不会互相 cancel。

配置项(锚点 / 吸附 / 手势 / 动画 / 持久化)与其他 host 完全一样,见 配置项FxControl 的方法见 API 速查


返回 Home · 相关:快速开始 配置项 常见问题 App 级全局浮窗

Clone this wiki locally