Android数据绑定:将变量传递给NavigationView

Kev*_*_TA 5 android android-layout android-databinding

当用户登录我的应用程序时,我在中收到其个人资料信息(名称,头像等)时MainActivity,我想通过数据绑定用用户参数填充“导航视图标题”中的某些字段。我已经尝试了docs中提出的方法,但也许仅限<include />于此?

activity_main.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="user"
            type="com.example.app.models.User" />
    </data>

    <android.support.v4.widget.DrawerLayout 
        // layout params... >

        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <android.support.design.widget.NavigationView xmlns:bind="http://schemas.android.com/apk/res-auto"
            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"
            bind:user="@{user}" />

    </android.support.v4.widget.DrawerLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

nav_header_main.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

    <variable
        name="user"
        type="com.example.app.models.User" />
</data>

<LinearLayout
    // layout params... >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:text="@{user.name}"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

</LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

主要活动

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setUser(User.getInstance());
// other stuff...
}
Run Code Online (Sandbox Code Playgroud)

我收到2个错误:

  1. 错误:找不到符号类ActivityMainBinding
  2. 在android.support.design.widget.NavigationView上找不到参数类型为com.example.app.models.User的属性“ bind:user”的设置器。

如果我删除bind:user它建立的行,但是它当然不起作用。有什么办法可以使这种事情起作用吗?

And*_*Dev 10

这对我有用:

活动_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
        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">

    <androidx.drawerlayout.widget.DrawerLayout
            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"/>

        <com.google.android.material.navigation.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"/>

    </androidx.drawerlayout.widget.DrawerLayout>

</layout>
Run Code Online (Sandbox Code Playgroud)

nav_header_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/layout_nav_view_header">

    <data>
        <variable
                name="user"
                type="com.myapp.model.UserSettings"/>
    </data>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/nav_header_height"
            android:background="@drawable/side_nav_bar"
            android:paddingBottom="@dimen/activity_vertical_margin"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            android:theme="@style/ThemeOverlay.AppCompat.Dark"
            android:orientation="vertical"
            android:gravity="bottom">

        <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingTop="@dimen/nav_header_vertical_spacing"
                app:srcCompat="@mipmap/ic_launcher_round"
                android:contentDescription="@string/nav_header_desc"
                android:id="@+id/imageView"/>

        <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingTop="@dimen/nav_header_vertical_spacing"
                android:text="@{user.name}"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/nav_header_subtitle"
                android:id="@+id/textView"/>

    </LinearLayout>

</layout>
Run Code Online (Sandbox Code Playgroud)

然后在活动的 onCreate 中:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val viewHeader = nav_view.getHeaderView(0)
    val navViewHeaderBinding : NavHeaderMainBinding = NavHeaderMainBinding.bind(viewHeader)
    navViewHeaderBinding.user = UserSettings(null, null, "John Doe", "Android Developer", null)
}
Run Code Online (Sandbox Code Playgroud)


小智 0

您需要以编程方式添加导航视图以启用绑定。

NavHeaderHomeBinding _bind = DataBindingUtil.inflate(getLayoutInflater(), R.layout.nav_header_main, binding
            .navView, false);
    binding.navView.addHeaderView(_bind);
Run Code Online (Sandbox Code Playgroud)

您的 xml :删除 headerLayout

<android.support.design.widget.NavigationView xmlns:bind="http://schemas.android.com/apk/res-auto"
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/activity_main_drawer"
        bind:user="@{user}" />
Run Code Online (Sandbox Code Playgroud)

这应该有效。