我读到使用Anko的最大好处是它的可重用性。但我无法找到其确切的例子。
目前在新的Android布局系统中,锅炉板如下:
DrawerLayout (with some setup)
CoordinatorLayout (with some setup)
AppBarLayout (with some setup)
ToolBar
<The Main Content>
NavigationView (with header inflated)
从上面的布局结构中,只有<The Main Content>
是varry。和
在许多情况下,这些仪式设置几乎在每个活动中都重复。
所以,Anko正在考虑是否有关于该问题的可重用解决方案。我不期望它可以重复用于通用布局,但至少我可以最小化项目中的仪式代码。也许我需要这样的东西:
class MainUI: AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>): View{
return with(ui) {
myCustomRootLayout {
//here is what <The Main Content> will be
}
}
}
}
从上面的代码我期待myCustomRootLayout
将完成根布局的所有仪式设置,如(DrawerLayout,CoordinatorLayout等)。
这可能吗?
修改 所以我认为我的问题是:如何制作可以托管其他组件的自定义组件
答案 0 :(得分:4)
重用代码的一种方法是简单地将myCustomRootLayout
提取到扩展方法中,如下所示:
class MainUI: AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>): View {
return with(ui) {
myCustomRootLayout {
recyclerView()
}
}
}
}
fun <T> AnkoContext<T>.myCustomRootLayout(customize: AnkoContext<T>.() -> Unit = {}): View {
return relativeLayout {
button("Hello")
textView("myFriend")
customize()
}
}
但是stated in the documentation:
虽然您可以直接使用DSL(
onCreate()
或任何地方) 在没有创建任何额外类的情况下,通常很方便 在单独的类中有UI。如果您使用提供的AnkoComponent 界面,您还可以免费获得DSL布局预览功能。
将可重用的部分提取到单独的AnkoComponent
:
class MainUI : AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>): View {
return with(ui) {
MyCustomRootLayout<MainActivity>({
recyclerView()
}).createView(ui)
}
}
}
class MyCustomRootLayout<T : Context>(val customize: AnkoContext<T>.() -> Unit = {}) : AnkoComponent<T> {
override fun createView(ui: AnkoContext<T>) = with(ui) {
relativeLayout {
button("Hello")
textView("myFriend")
customize()
}
}
}
答案 1 :(得分:3)
我实际上找到了一种方法来做到这一点,花了一些时间才弄明白。
我在这里有一个非常基本的测试布局,内容被添加到了
RelativeLayout
。
此处的关键是将自定义布局添加到委派给直接父级的委派AnkoContext
中(在我的情况下为RelativeLayout
)。
abstract class BaseAnkoComponent<T> : AnkoComponent<T> {
companion object {
val TOOLBAR_ID = View.generateViewId()
val COLLAPSING_ID = View.generateViewId()
val COORDINATOR_ID = View.generateViewId()
val APPBAR_ID = View.generateViewId()
val CONTENT_ID = View.generateViewId()
}
abstract fun <T> AnkoContext<T>.content(ui: AnkoContext<T>): View?
override fun createView(ui: AnkoContext<T>) = with(ui) {
coordinatorLayout {
id = COORDINATOR_ID
lparams(matchParent, matchParent)
appBarLayout(R.style.AppTheme_AppBarOverlay) {
id = APPBAR_ID
lparams(matchParent, wrapContent)
fitsSystemWindows = true
collapsingToolbarLayout {
id = COLLAPSING_ID
val collapsingToolbarLayoutParams = AppBarLayout.LayoutParams(matchParent, matchParent)
collapsingToolbarLayoutParams.scrollFlags = AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL or AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
layoutParams = collapsingToolbarLayoutParams
isTitleEnabled = false
toolbar {
id = TOOLBAR_ID
val toolbarLayoutParams = CollapsingToolbarLayout.LayoutParams(matchParent, dimenAttr(R.attr.actionBarSize))
toolbarLayoutParams.collapseMode = CollapsingToolbarLayout.LayoutParams.COLLAPSE_MODE_PIN
layoutParams = toolbarLayoutParams
minimumHeight = dimenAttr(R.attr.actionBarSize)
background = ColorDrawable(colorAttr(R.attr.colorPrimary))
popupTheme = R.style.AppTheme_PopupOverlay
}
}
}
with(AnkoContext.createDelegate(relativeLayout {
id = CONTENT_ID
val relativeLayoutParams = CoordinatorLayout.LayoutParams(matchParent, matchParent)
relativeLayoutParams.behavior = AppBarLayout.ScrollingViewBehavior()
layoutParams = relativeLayoutParams
})) {
content(ui)
}
}
}
}
然后您可以使用Anko DSL扩展BaseAnkoComponent
并以相同的方式构建您的内容。
class FooActivityUi : BaseAnkoComponent<FooActivity>() {
override fun <T> AnkoContext<T>.content(): View? {
return verticalLayout {
lparams(width = matchParent, height = matchParent)
button("Hello")
textView("myFriend")
}
}
}
我确信有更好的方法可以做到这一点,但我还没有找到它。有点新的Kotlin和Anko。