如何用Anko DSL制作通用的AppBar?

How to make universal AppBar with Anko DSL?

我正在尝试制作一个可以插入到其他 Anko 组件中的工具栏。这是我想要的示例:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        MainUI().setContentView(this)

        val toolbar: Toolbar = find(R.id.toolbar)
        setSupportActionBar(toolbar)
    }
}

class MainUI : AnkoComponent<MainActivity> {
    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        coordinatorLayout {
            fitsSystemWindows = true
            lparams {
                width = matchParent
                height = matchParent
            }
            ToolbarUI().createView(ui).lparams { width = matchParent }
            recyclerView {...}.lparams {
                width = matchParent
                height = matchParent
                behavior = AppBarLayout.ScrollingViewBehavior()
            }
        }
    }
}

class ToolbarUI : AnkoComponent<AppCompatActivity> {
    override fun createView(ui: AnkoContext<AppCompatActivity>) = with(ui) {
        appBarLayout {
            ...
            toolbar {
                setTitleTextColor(Color.WHITE)
                id = R.id.toolbar
                title = resources.getString(R.string.main_activity)
                ...
            }.lparams {
                width = matchParent
                height = wrapContent
            }
        }
    }
}

这样我就可以用更少的代码在其他地方使用相同的 AppBarLayout。但我得到这个: java.lang.IllegalStateException: View is already set: org.jetbrains.anko.design._AppBarLayout

任何人都可以帮助我以正确的方式实现它?

我能够使用基于 this answer 的 ViewManager 来做到这一点。

这是新代码:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        MainUI().setContentView(this)

        val toolbar: Toolbar = find(R.id.toolbar)
        setSupportActionBar(toolbar)
    }
}

class MainUI : AnkoComponent<MainActivity> {
    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        coordinatorLayout {
            fitsSystemWindows = true
            lparams {
                width = matchParent
                height = matchParent
            }
            toolbarUI(resources.getString(R.string.main_activity)).lparams { width = matchParent }
            recyclerView {...}.lparams {
                width = matchParent
                height = matchParent
                behavior = AppBarLayout.ScrollingViewBehavior()
            }
        }
    }

    fun ViewManager.toolbarUI(activity: String) = appBarLayout {
        toolbar {
            setTitleTextColor(Color.WHITE)
            id = R.id.toolbar
            title = activity
        }.lparams {
            width = matchParent
            height = wrapContent
        }
    }
}

问题是 ToolbarUI().createView(ui) 在同一个 AnkoContext 上创建视图,在 ui 上,默认情况下是用 setContentView = true 创建的。 您可以尝试使用另一个 AnkoContext,它不会将视图附加到 Activity:ToolbarUI().createView(AnkoContextImpl(activity, this /* parent ViewGroup */, true)).