簡體   English   中英

如何在android中將viewmodel綁定到嵌套視圖

[英]How to Bind viewmodel to nested view in android

將我的StaffViewModel數據綁定到具有DrawerLayoutNavigationView StaffActivity視圖。 在那個NavigationView有一個由員工姓名和電子郵件組成的布局nav_header_staf 我如何將我的視圖模型綁定到該nav_header_staff以替換員工姓名和電子郵件

我試圖在activity_staffnav_header_staff布局中的兩個布局中綁定視圖模型,但databinding不起作用。

這是我在 StaffActivity.kt 中嘗試過的

class StaffActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, AnkoLogger {

    private var fragmentManager: FragmentManager = supportFragmentManager
    private lateinit var drawerLayout: DrawerLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //Create View Model
        val staffBundle = intent.getBundleExtra(StaffModel.NAME)
        val staff = staffBundle.getSerializable(StaffModel.NAME) as StaffModel
        //Create databinding
        val staffViewModel = StaffViewModel(staff)
        val binding = DataBindingUtil.setContentView<ViewDataBinding>(this, R.layout.activity_staff)
        binding!!.setVariable(BR.staff, staffViewModel)

        val toolbar: Toolbar = toolbar
        setSupportActionBar(toolbar)

        val fab: FloatingActionButton = fab
        fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()
        }
        drawerLayout = drawer_layout
        val navView: NavigationView = nav_view

        val toggle = ActionBarDrawerToggle(
            this, drawerLayout, toolbar,
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close
        )
        drawerLayout.addDrawerListener(toggle)
        toggle.syncState()

        navView.setNavigationItemSelectedListener(this)
    }

這是 activity_staff.xml 布局

<layout>
    <data xmlns:android="http://schemas.android.com/apk/res/android">
        <variable name="staff" type="id.code.sakilarentaldvd.viewModel.StaffViewModel"/>
    </data>
    <androidx.drawerlayout.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_staff"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>


        <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_staff"
                app:menu="@menu/activity_staff_drawer"/>


    </androidx.drawerlayout.widget.DrawerLayout>
</layout>

這是 nav_header_staff.xml 布局

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data xmlns:android="http://schemas.android.com/apk/res/android">
        <variable name="staff" type="id.code.sakilarentaldvd.viewModel.StaffViewModel"/>
    </data>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:id="@+id/staffHeader"
        android:layout_height="@dimen/nav_header_height"
        xmlns:tools="http://schemas.android.com/tools"
        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"
            tools:text="username"
            android:text="@{staff.staffName}"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="blabla@sakila.org"
            android:text="@{staff.email}"
            android:id="@+id/textView"/>

</LinearLayout>
</layout>

這是結果的作用

在此處輸入圖片說明

謝謝stackoverflow,我知道我錯過了什么,這是我的解決方案

我在StaffActivity.kt變化

class StaffActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, AnkoLogger {

private var fragmentManager: FragmentManager = supportFragmentManager
private lateinit var drawerLayout: DrawerLayout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //Create View Model
    val staffBundle = intent.getBundleExtra(StaffModel.NAME)
    val staff = staffBundle.getSerializable(StaffModel.NAME) as StaffModel
    //Create databinding
    val staffViewModel = StaffViewModel(staff)
    //remove binding because no need to link view model with this layout
    setContentView(R.layout.activity_staff) // setActivityLayout

    ...

    // I override this object method
    val toggle =object: ActionBarDrawerToggle(
        this, drawerLayout, toolbar,
        R.string.navigation_drawer_open,
        R.string.navigation_drawer_close
    ){// do binding in this method
       override fun onDrawerStateChanged(newState: Int) {
            val binding2 = DataBindingUtil.bind<NavHeaderStaffBinding>(findViewById(R.id.staffHeader))
            binding2!!.staff= staffViewModel
            super.onDrawerStateChanged(newState)
        }
}
    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()

    navView.setNavigationItemSelectedListener(this)
}

通過刪除<layout><data>標簽,我對activity_staff.xml布局做了一些更改

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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_staff"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>


    <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_staff"
            app:menu="@menu/activity_staff_drawer"/>


</androidx.drawerlayout.widget.DrawerLayout>

所以這是結果

結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM