Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NotFoundException: String resource ID #0x0 when binding string resource

I'm currently using bindings to dynamically set the texts of various text views using the android view models. At the moment the view models look something like this:

class MyViewModel(
  resources: Resources,
  remoteClientModel: Model = Model()
) : ObservableViewModel() {

  init {
    observe(remoteClientModel.liveData) {
      notifyChange()
    }

  fun getTextViewTitle(): String = when {
    someComplicatedExpression -> resources.getString(R.string.some_string, null)
    else -> resources.getString(R.string.some_other_string)
  }
}

And the xml layout:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
  <import type="android.view.View"/>

  <variable
    name="viewModel"
    type="my.app.signature.MyViewModel"/>
  </data>

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

    <TextView
      android:id="@+id/title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@{viewModel.textViewTitle}"
      android:textAlignment="center"
      android:textStyle="bold"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="parent"/>

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

However I would like to remove the "resources: Resources" that is injected into the view model, since the resources are coupled with the Activity. The code now simply returns the string resource id instead:

  fun getTextViewTitle(): Int = when {
    someComplicatedExpression -> R.string.some_string
    else -> R.string.some_other_string
  }

Hence I've removed the activity dependency. The compiler thinks this is fine but it crashes in runtime with the following exception: android.content.res.Resources$NotFoundException: String resource ID #0x0.

This happens when trying to attach the lifeCycleOwner to the binding using:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    // Some more code....
    binding.lifecycleOwner = activity
    // Some more code....

I'm not sure how to remove the resource dependency from the view model without having it crash in runtime.

EDIT:

For clarification: The ObservableViewModel in my example is the very same one as the one found here:

https://developer.android.com/topic/libraries/data-binding/architecture

Used to perform notifyChange.

like image 837
Salladsmannen Avatar asked Jun 13 '26 05:06

Salladsmannen


2 Answers

The issue here is the code is trying to call textView.setText(0) which results in an error since there is no string resource with id 0x0. This is happening because getTextViewTitle() return an Int and the view binding functionality will make it default as 0 (when initializing).

https://developer.android.com/topic/libraries/data-binding/expressions#property_reference

From the docs

Avoiding null pointer exceptions

Generated data binding code automatically checks for null values and avoid null pointer exceptions. For example, in the expression @{user.name}, if user is null, user.name is assigned its default value of null. If you reference user.age, where age is of type int, then data binding uses the default value of 0.

Maybe something like this could work,

android:text='@{viewModel.textViewTitle == 0 ? "" : @string{viewModel.textViewTitle}}'

or

android:text='@{viewModel.textViewTitle, default=""}'
like image 113
Froyo Avatar answered Jun 14 '26 19:06

Froyo


To solve this simply make a context available in the view, so that you can call context.getString(...) in your view.

 <data>
    <import type="androidx.core.content.ContextCompat" />

    <variable
      name="viewModel"
      type="my.application.path.SomeViewModel" />
 </data>

  <....
      ....
      android:text="@{context.getString(viewModel.textResource)}"
      ...
  />
like image 27
Salladsmannen Avatar answered Jun 14 '26 19:06

Salladsmannen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!