在Android Kotlin中,Fragment中的DataBinding和ViewModel

5

我是DataBinding的新手。我想在Fragment中使用ViewModel和DataBinding。当我在Activity中使用时,它可以正常工作,但在Fragment中却无法正常工作。请帮忙使用数据绑定获取EditText的内容。先谢谢了。

MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

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

        supportFragmentManager.beginTransaction().add(R.id.main,BlankFragment()).commit()

    }
}

activity.main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main"
    tools:context=".MainActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

BlankFragment.kt

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.resocoder.databinding.databinding.FragmentBlankBinding

class BlankFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val binding: FragmentBlankBinding = DataBindingUtil.inflate(inflater,
                R.layout.fragment_blank, container, false)

        return binding.root
    }

}

fragment_blank.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="viewmodel"
            type="com.resocoder.databinding.MainViewModel"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".BlankFragment">

        <EditText
            android:id="@+id/editText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:text="@={viewmodel.editTextContent}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:text="Display in Log"
            android:onClick="@{() -> viewmodel.onDisplayEditTextContentClick()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/editText"
            app:layout_constraintVertical_bias="0.0" />

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

MainViewModel.kt

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class MainViewModel : ViewModel() {

    val editTextContent = MutableLiveData<String>()

    fun onDisplayEditTextContentClick() {
        Log.d("Murad",""+editTextContent.value)
    }
}
2个回答

12

您的 ViewModelFragment 没有任何连接。

请按照以下方式进行操作:

BlankFragment:

  private lateinit var vm: MainViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)    
         vm = activity?.run {
                ViewModelProviders.of(this)[MainViewModel::class.java]
            } ?: throw Exception("Invalid Activity")       
        }

      override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val binding: FragmentBlankBinding = DataBindingUtil.inflate(inflater,
                R.layout.fragment_blank, container, false)
           binding.viewmodel = vm//attach your viewModel to xml
        return binding.root
      }
    }

1

here how it works with fragment

class UpdateFragment : Fragment() {

private lateinit var _binding: FragmentUpdateBinding
private val binding get() = _binding

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    _binding = FragmentUpdateBinding.inflate(inflater,container,false)

    // here goes the code

    return binding.root
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接