Issue
I have a BaseFragment class:
abstract class BaseFragment: Fragment(), View.OnClickListener {
private lateinit var mBinding: ViewDataBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = DataBindingUtil.inflate<ViewDataBinding>(inflater, getLayoutId() , container, false)
return mBinding.root
}
abstract fun getLayoutId(): Int
abstract fun afterOnViewCreated()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
afterOnViewCreated()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
}
override fun onClick(v: View?) { }
fun getViewDataBinding(): ViewDataBinding {
return mBinding
}
fun setClickListener(vararg views: View) {
views.forEach { view -> view.setOnClickListener(this) }
}
}
Which i extend to create new fragments like this:
class HomeFragment : BaseFragment() {
private lateinit var homeViewModel: HomeViewModel
override fun getLayoutId(): Int {
return R.layout.fragment_home
}
override fun afterOnViewCreated() {
activity?.let{
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
}
//TODO:
}
}
But, im getting this crash:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mu.chatonymous, PID: 23328
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.IllegalStateException: DataBindingUtil.inflate<…nt_home, container, false) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3318)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3429)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2009)
at android.os.Handler.dispatchMessage(Handler.java:109)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7555)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
Caused by: java.lang.IllegalStateException: DataBindingUtil.inflate<…nt_home, container, false) must not be null
at com.mu.chatonymous.ui.base.BaseFragment.onCreateView(BaseFragment.kt:21)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2612)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:874)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2087)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1861)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1817)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1717)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2650)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2600)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2639)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:897)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1228)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1293)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2646)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2600)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:176)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1340)
at android.app.Activity.performStart(Activity.java:7364)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3281)
heres my app level build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'io.fabric'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.mu.chatonymous"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
//androidx
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-runtime:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
kapt 'androidx.lifecycle:lifecycle-compiler:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
//for selection single or multiple items in recycler view
implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
}
//test
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
//google
dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.firebase:firebase-analytics:17.2.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation 'com.google.firebase:firebase-auth:19.2.0'
}
//3rd party
dependencies {
implementation 'com.jakewharton.timber:timber:4.7.1'
}
apply plugin: 'com.google.gms.google-services'
What am i doing wrong? i know i can use LayoutInflater.inflate instead of DatabindingUtil.inflate, but ive used this flow without problems before. And i kind off need the viewDataBinding object for later use like i did here.
Solution
Okay, so i found the issue. Turns out even if u configured almost every setting properly you might forget/miss out on this little info. So, i'll share what i learnt here.
Data binding layout files are slightly different and start with a root tag of <layout>
followed by a data element and a view root element. As mentioned in detail here: Official Databinding Documentation
So wrapping all your layouts with <layout></layout>
will remedy this exception.
e.g:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
....
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Answered By - because_im_batman
Answer Checked By - Willingham (JavaFixing Volunteer)