8

I am implementing ViewBinding in one of my fragments. This fragment has a layout included like so:

...
<androidx.core.widget.NestedScrollView
        android:id="@+id/sv_sudf_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/btn_sudf_continue"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/eav_sudf_avatar">

        <include
            android:id="@+id/l_sudf_details"
            layout="@layout/layout_sign_up_details_fields"/>

    </androidx.core.widget.NestedScrollView>
...

I have followed this answer but it also does not work.

The generated view binding class for the fragment has the binding inside, however, the type for the attribute is View. When I then reference the View using binding.lSudfDetails the type is LayoutSignUpDetailFieldsBinding. Where this type is coming from I can't work out as there is no generated class with that name however, I would expect it would assign it the proper binding type. Here is the attribute in the FragmentSignUpDetailsBinding.java.

@NonNull
public final View lSudfDetails;

The bindings are all correctly setup however and it allow me to reference views within the nested layout but when I come to build I get unresolved reference errors. Lint does not complain when I reference them like this:

binding.lSudfDetails.etSudfDob

The compiler does fail however with errors such as this

Unresolved reference: etSudfDob

The binding itself is created according to the Android docs:

private var _binding : FragmentSignUpDetailsBinding? = null
private val binding get() = _binding!!

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        _binding = FragmentSignUpDetailsBinding.inflate(inflater,container,false)
        return binding.root
    }

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    binding.tvSudfWelcome.text = getString(R.string.sign_up_welcome,getString(R.string.app_name))
    binding.lSudfDetails.etSudfDob.setOnClickListener {
            showYearSelection()
    }
}

The tvSudfWelcome binding works its the nested binding it doesn't like.

StuStirling
  • 15,601
  • 23
  • 93
  • 150

4 Answers4

4

If you're using Android Studio 3.6.0 sometimes gradle plugin fails to generate ViewBinding fields for included layouts. Please update to Android Studio 3.6.1 and gradle plugin version to 3.6.1.

Somesh Kumar
  • 8,088
  • 4
  • 33
  • 49
  • Another one if you can help - https://stackoverflow.com/q/60549985/507313 – StuStirling Mar 05 '20 at 16:29
  • im using the latest AS and still get this issue – Jono Jul 29 '21 at 10:54
  • 2
    @Jonathan Check if there are generated classes (after succefully build) inside `app > build > generated > data_binding_base_class_source_out` folder? – Somesh Kumar Jul 29 '21 at 11:20
  • 1
    Found out the issue, it was to do with the included xml layout not having a Layout viewgroup as its root one. I had a CardView as its root layout – Jono Jul 29 '21 at 15:20
2

If someone has similar problem... I solved my problem with adding width and height for this included view. It helped, I do not have any idea why, but this would be my solution:

 <include
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/l_sudf_details"
        layout="@layout/layout_sign_up_details_fields"/>
0

If someone has a similar problem - I solved mine using:

execute gradle task : prepareKotlinBuildScriptModel

Dev Sebastian
  • 587
  • 6
  • 11
0

changing the id name to the same as the layout name worked for me. For eg:

<include
            android:id="@+id/layout_sign_up_details_fields"
            layout="@layout/layout_sign_up_details_fields"/>

I was working with databinding instead of viewbinding though

Narendra_Nath
  • 4,578
  • 3
  • 13
  • 31