Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用MVVM和数据绑定更改每个片段中的工具栏标题_Android_Kotlin_Android Toolbar_Android Databinding_Android Mvvm - Fatal编程技术网

Android 使用MVVM和数据绑定更改每个片段中的工具栏标题

Android 使用MVVM和数据绑定更改每个片段中的工具栏标题,android,kotlin,android-toolbar,android-databinding,android-mvvm,Android,Kotlin,Android Toolbar,Android Databinding,Android Mvvm,我希望在我的片段页面中更改主活动中的工具栏标题。我的项目基于MVVM体系结构,带有数据绑定 这是我的主要活动。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

我希望在我的片段页面中更改主活动中的工具栏标题。我的项目基于MVVM体系结构,带有数据绑定

这是我的主要活动。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">
<data>
    <variable
        name="viewModel"
        type="com.lalsoft.toolbar_mvvm_databinding.viewmodel.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.MainActivity">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:elevation="0dp"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:minHeight="?attr/actionBarSize"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:titleTextColor="@android:color/white"
            app:navigationIcon="@drawable/ic_arrow_back"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:navigationOnClickListener="@{()->viewModel.navBackClicked()}"
            app:title="@{viewModel.toolbarTitle}"/>
    </com.google.android.material.appbar.AppBarLayout>

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

我也在为同样的问题挣扎! 我认为问题在于生命周期所有者。但是找不到答案。 目前,我观察ViewModel中的值,并在观察者内部指定值。 但我认为还有更好的办法

我和同样的人斗争! 我认为问题在于生命周期所有者。但是找不到答案。 目前,我观察ViewModel中的值,并在观察者内部指定值。
但我认为还有更好的办法

如果片段使用的是ViewModel,则应将其作用域限定为主机活动,请由activityViewModels()委托使用:

    @AndroidEntryPoint
    class HomeFragment : Fragment() {
      private val viewModel: SharedViewModel by activityViewModels()
    }
我认为这个答案也会有所帮助


当您使用by viewModels时,您正在创建一个作用域为该单个片段的ViewModel—这意味着每个片段都有其自己的ViewModel类实例。如果希望单个ViewModel实例的作用域为整个活动,则希望按activityViewModels使用

如果片段正在使用ViewModel,则应将其作用域为主机活动,则按activityViewModels()委托使用:

    @AndroidEntryPoint
    class HomeFragment : Fragment() {
      private val viewModel: SharedViewModel by activityViewModels()
    }
我认为这个答案也会有所帮助

当您使用by viewModels时,您正在创建一个作用域为该单个片段的ViewModel—这意味着每个片段都有其自己的ViewModel类实例。如果希望单个ViewModel实例的作用域为整个活动,则希望由activityViewModels使用

private const val TAG = "FirstViewModel"

class FirstViewModel : MainViewModel() {

private val _navigateToDetails = MutableLiveData<Event<String>>()
val navigateToFragment: LiveData<Event<String>>
    get() = _navigateToDetails

init {
    Log.e(TAG, "Inside Init")
    toolbarTitle.value="First Fragment"
}

fun onBtnClick() {
    _navigateToDetails.value = Event("Second Fragment")
}
}
private const val TAG = "FirstFragment"

class FirstFragment : Fragment() {
private lateinit var viewModel: FirstViewModel
private lateinit var dataBinding: FirstFragmentBinding

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    dataBinding = DataBindingUtil.inflate(inflater, R.layout.first_fragment, container, false)
    return dataBinding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewModel = ViewModelProvider(this).get(FirstViewModel::class.java)
    viewModel.toolbarTitle.observe(viewLifecycleOwner, toolbarTitleObserver)
    viewModel.navigateToFragment.observe(viewLifecycleOwner, navigateToFragmentObserver)
    //(activity as MainActivity?)!!.toolbar.title = "Check"
    dataBinding.viewModel = viewModel

}


private val toolbarTitleObserver = Observer<String> {
    Log.e(TAG, "Title set : $it")
    //(activity as MainActivity?)!!.toolbar.title = "Check"
    //Log.e(TAG, "Title set : Check")
}

private val navigateToFragmentObserver = Observer<Event<String>> { it ->
    it.getContentIfNotHandled()?.let { // Only proceed if the event has never been handled
        Log.i(TAG, "checkIt string $it")
        parentFragmentManager.beginTransaction().replace(
            R.id.fragment_container,
            SecondFragment()
        ).addToBackStack(null).commit()

    }
}
}
    @AndroidEntryPoint
    class HomeFragment : Fragment() {
      private val viewModel: SharedViewModel by activityViewModels()
    }