在一般的XML布局中,默认的主要布局是这样的:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
我尝试使用Anko DSL编写代码:
...
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
drawerLayout {
lparams(width = matchParent, height = matchParent)
id = ID_DRAWER_LAYOUT
fitsSystemWindows = true
navigationView {
lparams(width = wrapContent, height = matchParent)
id = ID_NAVIGATION_VIEW
foregroundGravity = Gravity.START
fitsSystemWindows = true
addHeaderView(navHeaderView()) //// PROBLEM HERE ////
inflateMenu(R.menu.activity_main_drawer)
}
}
}
private fun ViewGroup.navHeaderView() {
linearLayout {
lparams(width = matchParent, height = dip(160))
backgroundResource = R.drawable.side_nav_bar
gravity = Gravity.BOTTOM
orientation = LinearLayout.VERTICAL
setPadding(dip(64), dip(16), dip(64), dip(16))
imageView {
id = ID_IMAGE_VIEW
topPadding = dip(16)
imageResource = android.R.drawable.sym_def_app_icon
}
textView {
lparams(width = matchParent, height = wrapContent)
id = ID_TEXT_NAME
topPadding = dip(16)
text = "test1"
if (Build.VERSION.SDK_INT >= 23) {
setTextAppearance(R.style.TextAppearance_AppCompat_Body1)
} else {
setTextAppearance(context, android.R.style.TextAppearance_Medium)
}
}
textView {
id = ID_TEXT_DESCRIPTION
text = "test2"
}
}
}
...
标记的行会抛出一个异常,表示该视图已经有一个父级。
然后我尝试使用Anko DSL预览插件自动转换xml,就像这样做,没有完全改成Anko DSL:
android.support.v4.widget.DrawerLayout {
id = Ids.drawer_layout
include<View>(R.layout.app_bar_main).lparams(width = matchParent, height = matchParent)
org.mewx.projectprpr.template.NavigationFitSystemView {
id = Ids.nav_view
app:headerLayout = @layout/nav_header_main //// HERE ////
app:menu = @menu/activity_main_drawer
}.lparams(width = wrapContent, height = matchParent)
}
如何使用Anko DSL添加标题视图?
谢谢!
答案 0 :(得分:3)
首先,DrawerLayout在其构造函数中检查fistSystemWindows
并设置状态栏背景,因此,遗憾的是,使用DrawerLayout和fitsSystemWindows
的最简单方法是将其从XML中膨胀。
其次,Anko DSL方法不仅可以创建新视图,还可以将它们附加到父视图。您必须创建一个分离视图:
addHeaderView(UI {
navHeaderView()
}.view)
此代码适用于Anko 0.10.0-beta-2
,行为甚至语法可能因版本而异。
第三,我发现了一个错误:当我在显示键盘时打开抽屉时,标题视图会获得较大的底部填充(插入)。我悲伤的解决方法看起来像这样:
addHeaderView(
object : _RelativeLayout(context) { // fixes bottomPadding with open keyboard :'(
@TargetApi(20) override fun onApplyWindowInsets(insets: WindowInsets) =
insets.consumeSystemWindowInsets()
}.apply {
/* DSL code here */
})