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

时间:2017-05-31 06:38:45

标签: android kotlin kotlin-android-extensions anko

我正在尝试创建一个可以插入其他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

任何人都可以用正确的方法帮助我实现这个目标吗?

2 个答案:

答案 0 :(得分:2)

我能够使用基于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
        }
    }
}

答案 1 :(得分:1)

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