Android 视图未通过数据绑定进行更新
Android View is not updating over data binding
我创建了一个简单的应用程序,它从 API 加载随机笑话并将其显示在 TextView 中。出于学习原因,我已经使用数据绑定实现了该应用程序。起初我创建了一个 ViewModel,它从 API
中获取数据
class RandomJokeViewModel: ViewModel() {
private val jokeService = RetrofitService()
fun getRandomJoke(): MutableLiveData<RandomJoke> ? {
Log.e("getRandomJokeData", "yes")
return jokeService.loadRandomJoke()
}
在我的 Fragment 中,我调用了加载笑话和更新视图的方法
class RandomJokeFragment : Fragment() {
private lateinit var binding: FragmentRandomJokeBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_random_joke, container, false)
binding.lifecycleOwner = this
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_random_joke, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadRandomJoke()
}
private fun loadRandomJoke() {
Log.e("getAndroidVersion", "yes")
val randomJokeViewModel =
ViewModelProviders.of(requireActivity()).get(RandomJokeViewModel::class.java)
randomJokeViewModel.getRandomJoke()?.observe(this, Observer<RandomJoke> { randomJoke ->
binding.randomJoke = randomJoke
Log.e("RandomJokeFragment", "This is your Joke: ${randomJoke.value}")
})
}
我的数据调用如下所示:
data class RandomJoke (
@SerializedName("categories") val categories: ArrayList<String>,
@SerializedName("created_at") val createdAt: String,
@SerializedName("icon_url") val iconUrl: String,
@SerializedName("id") val id: String,
@SerializedName("updated_at:") val updatedAt: String,
@SerializedName("url") val url: String,
@SerializedName("value") val value: String)
在我的片段布局中,我定义了这样的数据绑定资源
<data>
<variable
name="randomJoke" type="com.example.jokegenerator.data.remote.response.RandomJoke"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginStart="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@{randomJoke.value}"
android:textColor="#ffff"
tools:text="Hello World"/>
</androidx.constraintlayout.widget.ConstraintLayout>
所以当我 运行 应用程序时,我的 TextView 是空的。在 Logcat 和我验证的调试器中,randomJoke
响应有数据。为什么获取数据后我的视图没有更新?我错过了什么?
不完全确定是这个原因但是:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_random_joke, container, false)
binding.lifecycleOwner = this
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_random_joke, container, false)
}
在这里,您将布局膨胀 2 次。
改为这样尝试:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// This will inflate your layout. You just have to return the root view.
binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_random_joke, container, false)
binding.lifecycleOwner = this
return binding.root // Returning your root view
}
数据绑定可能是两种布局的混合。
在您的 onCreateView() 中,您 return在:
return inflater.inflate(R.layout.fragment_random_joke, container, false)
但你需要 return:
return binding.root
我创建了一个简单的应用程序,它从 API 加载随机笑话并将其显示在 TextView 中。出于学习原因,我已经使用数据绑定实现了该应用程序。起初我创建了一个 ViewModel,它从 API
中获取数据class RandomJokeViewModel: ViewModel() {
private val jokeService = RetrofitService()
fun getRandomJoke(): MutableLiveData<RandomJoke> ? {
Log.e("getRandomJokeData", "yes")
return jokeService.loadRandomJoke()
}
在我的 Fragment 中,我调用了加载笑话和更新视图的方法
class RandomJokeFragment : Fragment() {
private lateinit var binding: FragmentRandomJokeBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_random_joke, container, false)
binding.lifecycleOwner = this
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_random_joke, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadRandomJoke()
}
private fun loadRandomJoke() {
Log.e("getAndroidVersion", "yes")
val randomJokeViewModel =
ViewModelProviders.of(requireActivity()).get(RandomJokeViewModel::class.java)
randomJokeViewModel.getRandomJoke()?.observe(this, Observer<RandomJoke> { randomJoke ->
binding.randomJoke = randomJoke
Log.e("RandomJokeFragment", "This is your Joke: ${randomJoke.value}")
})
}
我的数据调用如下所示:
data class RandomJoke (
@SerializedName("categories") val categories: ArrayList<String>,
@SerializedName("created_at") val createdAt: String,
@SerializedName("icon_url") val iconUrl: String,
@SerializedName("id") val id: String,
@SerializedName("updated_at:") val updatedAt: String,
@SerializedName("url") val url: String,
@SerializedName("value") val value: String)
在我的片段布局中,我定义了这样的数据绑定资源
<data>
<variable
name="randomJoke" type="com.example.jokegenerator.data.remote.response.RandomJoke"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginStart="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@{randomJoke.value}"
android:textColor="#ffff"
tools:text="Hello World"/>
</androidx.constraintlayout.widget.ConstraintLayout>
所以当我 运行 应用程序时,我的 TextView 是空的。在 Logcat 和我验证的调试器中,randomJoke
响应有数据。为什么获取数据后我的视图没有更新?我错过了什么?
不完全确定是这个原因但是:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_random_joke, container, false)
binding.lifecycleOwner = this
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_random_joke, container, false)
}
在这里,您将布局膨胀 2 次。
改为这样尝试:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// This will inflate your layout. You just have to return the root view.
binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_random_joke, container, false)
binding.lifecycleOwner = this
return binding.root // Returning your root view
}
数据绑定可能是两种布局的混合。
在您的 onCreateView() 中,您 return在:
return inflater.inflate(R.layout.fragment_random_joke, container, false)
但你需要 return:
return binding.root