如何使用Anko DSL设置NavigationView的headerView?

在一般的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?

谢谢!

首先,DrawerLayout在其构造函数中检查fistSystemWindows并设置状态栏的背景,所以不幸的是,使用SuitSystemWindows最简单的方法是使用DrawerLayout来从XML中fitsSystemWindows它。

其次,Anko DSL方法不仅可以创建新的视图,还可以将它们附加到父项目中。 您必须创建一个分离的视图:

 addHeaderView(UI { navHeaderView() }.view) 

此代码旨在与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 */ })