Home > Enterprise >  Errors with android:id fields in layouts not anymore recognized
Errors with android:id fields in layouts not anymore recognized

Time:03-09

Following an upgrade of android-studio, kotlin plugins and sourceCompatibility to Java 8 in an android project, many layout ids are not any more recognized (but strangely not all). It looks like field name with underscores are not recognized in binding.

For instance: whith the following declaration in the layout

<TextView
            android:id="@ id/alert_hist_item__equipement"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5px"
            android:text="@string/Device"
            android:textStyle="bold"
            />

in the code

alert_hist_item__equipement.text = "x"

is not recognized but

alertHistItemEquipement.text = "x"

is recognized.

If I change the field names in the layouts to equivalent camel case names (either only in the code, with the names in the layout still having underscores; or both in code and layout) the fields are recognized.

It is so painful for many reasons:

  1. I have dozens of layouts all with id names containing underscore
  2. I find names with underscore easier to read (and my team too)
  3. it was never specified that android:id fields should follow certain rules

is this possible to change that behavior ? Could it be a bug ?

CodePudding user response:

It is a sad and unfortunate constraint that comes from the new autogenerated binding class. This is specified in https://developer.android.com/topic/libraries/data-binding/expressions it says:

Note: The binding class converts IDs to camel case.

CodePudding user response:

Please add following id 'kotlin-android-extensions' to you app level gradle.

plugins {
    id 'kotlin-android-extensions'
}

According to Kotlin documentation they are deprecated but they are still working for me.

As and alternate they provide us with data and view binding. For you View Binding should work!

here is the example:

add following to your app level gradle:

buildFeatures{
        viewBinding true
    }

then in you activity declare as following (Assuming you activity name is ManuelYguel)

class ManuelYguel : AppCompatActivity() {
     private lateinit var binding: ActivityManuelYguelBinding

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityManuelYguelBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.alertHistItemEquipement.text = "x"
    }
}
  • Related