19

This is from the google site: A binding class is generated for each layout file. By default, the name of the class is based on the name of the layout file, converting it to Pascal case and adding the Binding suffix to it. The above layout filename is activity_main.xml so the corresponding generated class is ActivityMainBinding. This class holds all the bindings from the layout properties (for example, the user variable) to the layout's views and knows how to assign values for the binding expressions.

In my case ActivityMainBinding is generated, but not ActivityMainBindingImpl. What is that class? How does it get generated? My project is written in Kotlin.

import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.View;
import androidx.databinding.DataBinderMapper;
import androidx.databinding.DataBindingComponent;
import androidx.databinding.ViewDataBinding;
import com.example.drake.kunuk.databinding.ActivityMainBindingImpl;
import java.lang.IllegalArgumentException;
import java.lang.Integer;
import java.lang.Object;
import java.lang.Override;
import java.lang.RuntimeException;
import java.lang.String;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class DataBinderMapperImpl extends DataBinderMapper {
  private static final int LAYOUT_ACTIVITYMAIN = 1;

  private static final SparseIntArray INTERNAL_LAYOUT_ID_LOOKUP = new SparseIntArray(1);

  static {
    INTERNAL_LAYOUT_ID_LOOKUP.put(com.example.drake.kunuk.R.layout.activity_main, LAYOUT_ACTIVITYMAIN);
  }

  @Override
  public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
    int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
    if(localizedLayoutId > 0) {
      final Object tag = view.getTag();
      if(tag == null) {
        throw new RuntimeException("view must have a tag");
      }
      switch(localizedLayoutId) {
        case  LAYOUT_ACTIVITYMAIN: {
          if ("layout/activity_main_0".equals(tag)) {
            return new ActivityMainBindingImpl(component, view);
          }
      throw new IllegalArgumentException("The tag for activity_main is invalid. Received: " + tag);
    }
  }
}
return null;
  }

my xml:

<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="handler"
            type="com.example.drake.kunuk.ui.main.MainActivity" />
    <variable
            name="manager"
            type="androidx.fragment.app.FragmentManager" />
</data>

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true"
            app:title="@string/app_name"
            app:titleMarginStart="8dp" />

    <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:pager="@{(pager)}">
    </com.google.android.material.tabs.TabLayout>

    <androidx.viewpager.widget.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:handler="@{handler}" />

</LinearLayout>

MainActivity.kt:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.drake.kunuk.R
import com.example.drake.kunuk.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding: ActivityMainBinding = DataBindingUtil
        .setContentView(this, R.layout.activity_main)
    binding.handler = this
    binding.manager = supportFragmentManager



}

}

Dr4ke the b4dass
  • 1,184
  • 2
  • 17
  • 40

3 Answers3

26

The likely cause is an error in the data binding stage.

The data binding compiler takes layout files and generates classes to support data binding (as you note: ActivityMainBinding, ActivityMainBindingImpl; the general pattern, dear readers, is {layout}Binding and {layout}BindingImpl, where {layout} is the camel-cased name of the layout file). Errors that arise during data binding compilation prevent these support classes from being generated. This then causes the missing class error you see from the Kotlin or Java compiler.

Currently, data binding errors aren't shown in the cooked build log; to see them, switch the view to the raw compiler output. Starting around AS 3.5, data binding errors should be shown in the cooked log.

Once you locate the error message from the data binding compiler, you can fix it, or look for an answer here on how to fix it if you're not sure.

outis
  • 75,655
  • 22
  • 151
  • 221
6

in dataBinding pattern if u have any wrong (without any runtime error) in layout.xml or in activity ... You have not this class .. and in kotlin be sure if u add dataBinding like this :

android {
   //
        }
    }

    dataBinding {
        enabled = true
    }
}

and :

// notice that the compiler version must be the same than our gradle version
kapt 'androidx.databinding:databinding-compiler:3.2.1'

should be Ok.

Sana Ebadi
  • 6,656
  • 2
  • 44
  • 44
2

Re-check your xml file there could be some issue, run the gradle task "kaptDebugkotlin" under other section & see in the logCat

An exception occurred: android.databinding.tool.util.LoggedErrorException: Found data binding errors.

enter image description here

Pankaj kumar
  • 1,357
  • 14
  • 13