ViewBinding: Cannot access '<init>': it is private in 'ActivityMainBinding' - android

I've tried multiple solutions and read some other answers talking about the visibility of the class, but I've no added any private or protected modifier.
The point is, that I'm just have a very simple ViewBinding configuration, but it's showing the following message when I try to run it.
e: /app/src/main/java/com/adalpari/example/view/MainActivity.kt: (16,40): Cannot access '': it is private in 'ActivityMainBinding'
e: /app/src/main/java/com/adalpari/example/view/MainActivity.kt: (16,60): No value passed for parameter 'rootView'
e: /app/src/main/java/com/adalpari/example/view/MainActivity.kt: (16,60): No value passed for parameter 'progressBar'
e: /app/src/main/java/com/adalpari/example/view/MainActivity.kt: (16,60): No value passed for parameter 'storiesView'
The code, as you can see is pretty simple..
MainActivity:
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
val binding: ActivityMainBinding = ActivityMainBinding()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
onObserve()
}
...
}
xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.MainActivity"
>
<com.adalpari.storiesview.view.StoriesView
android:id="#+id/stories_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="#+id/stories_view"
app:layout_constraintEnd_toEndOf="#+id/stories_view"
app:layout_constraintStart_toStartOf="#+id/stories_view"
app:layout_constraintTop_toTopOf="#+id/stories_view"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
And finally the enabling of ViewBinding in app's gradle:
apply plugin: 'kotlin-kapt'
android {
...
buildFeatures {
viewBinding true
}
...
}
Any help is very appreciated, thanks in advance!

You're not supposed to use the constructors of data binding classes (they're private, as your error message says). Use the method ActivityMainBinding.inflate() to create your binding object
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
This is shown in the official docs for ViewBinding

I would recommend using dataBinding which includs viewBinding and other powerful features you may need in the future.
1. Enable dataBinding in Build Gradle File:
apply plugin: 'kotlin-kapt'
android {
...
buildFeatures {
dataBinding true
}
...
}
2. Wrap the Whole Layout inside <layout> Tag:
<layout //key point
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="#+id/xxx"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
...
</LinearLayout>
</layout>
3. Setup Activity/Fragment:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding //may need rebuild project
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//binding.xxx.xxx
}
}
For Fragment:
binding: FragmentFirstBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_first, container, false)

Related

On Click event Does not working with Data Binding in Android Studio

I am learning DataBinding in android studio. But I am facing a problem with binding a ModelView. I want to bind a function with a button on click event. I set a function in the model view. I want to update my text view with on click event of my button. But When I click the button my text is not updating. I can not understand what I have done wrong.
XML layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="model"
type="com.example.jetpack.MainModelView" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{model.title}"
android:textSize="28sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Update Text"
android:onClick="#{()-> model.update()}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Main Model View:
class MainModelView : ViewModel() {
var title: String = " This is My Application"
fun update() {
title = "I am Changed"
Log.d("UPDATE", "update successfully from main model view")
}
}
Main Activity:
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
lateinit var mainModelView: MainModelView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
mainModelView = ViewModelProvider(this).get(MainModelView::class.java)
binding.model = mainModelView
}
}
My app Image:
thanks in advance for helping.
The title variable in ViewModel needs to be a ObservableField or LiveData otherwise you xml will never know when it's value got updated –
class MainViewModel : ViewModel() {
var text = MutableLiveData(" Welcome to my application ")
fun updateText() {
text.value = " Text is updated successfully "
}
}
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
// Creating MainViewModel object
mainViewModel = MainViewModel()
// Binding mainViewModel variable
// with MainViewModel object
binding.mainViewModel = mainViewModel
// passing LifeCycleOwner to binding object
binding.lifecycleOwner = this
}
}

Android Kotlin - viewBinding Type mismatch: inferred type is DrawerLayout but ConstraintLayout was expected

I'm trying to get viewBinding to work.
This is the code:
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view: ConstraintLayout = binding.root
setContentView(view)
}
I manually declared the type ConstraintLayout because it's what I'm using for that activity called AskProfileImage:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#303030"
tools:context=".AskProfileImage">
<ImageView
android:id="#+id/imageView97545"
android:layout_width="108dp"
android:layout_height="64dp"
android:layout_marginTop="8dp"
android:background="#00FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/logo2" />
But I'm getting the error
Type mismatch: inferred type is DrawerLayout but ConstraintLayout was expected
on
binding.root
how to fix this?
viewBinding creates a class for each activity. So in my case for this activity it's:
ActivityAskProfileImageBinding
So the correct code is:
private lateinit var binding: ActivityAskProfileImageBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAskProfileImageBinding.inflate(layoutInflater)
setContentView(binding.root)
}
Since viewBinding is probably broadly used now, I don't understand why the hell nobody could answer that and why google docs are as always useless

Android : Kotlin : MVVM : Why viewModel.onButtonClicked() causes the app crash?

Logcat Message :
java.lang.IllegalStateException: Could not find method #={() -> viewModel.onBtnClicked()(View) in a parent or ancestor Context for android:onClick attribute defined on view class androidx.appcompat.widget.AppCompatButton with id 'button'
File1 : activity_main.xml
<data>
<variable
name="viewModel"
type="com.wingsquare.databindingdemo.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:onClick = "#={() -> viewModel.onBtnClicked()"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
File 2 : MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main)
// val binding = ActivityMainBinding.inflate(layoutInflater)
val mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
binding.viewModel = mainViewModel
binding.lifecycleOwner = this
}
}
File 3 : MainViewModel.kt
class MainViewModel : ViewModel() {
fun onBtnClicked() {
Log.d("MainViewModel", "MainViewModel")
}
}
The Logcat Message is some how misleading.
I was facing the same error for couple of hours checking everything else I thought it be the root cause. But for this particular error, all you have to do is to keep an eye on "{ }". This is one of the drawbacks of data binding in android. lots of the times you don't get any error on compile times, And if you do! that's not really helpful !
and another thing to consider is that '=' in
android:onClick = "#={() -> viewModel.onBtnClicked()}"
is used for a two way binding.
you don't need it in this case.
you can read about it here on android official docs
android:onClick="#{() -> viewModel.onBtnClicked()}"
Add a parenthesis at the end.
also you may want to remove the equal sign after the #

Android view binding root property ignored

I'm trying to use View Binding in android, but the root's property (layout_gravity, layout_width) got ignored after build and installed,
it looks fine on design view (wrap_content and center_vertical).
i've enabled viewBinding in app gradle (android studio 3.6.1), and my root view group is a LinearLayout with some property
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical"
tools:context=".MainActivity">
...
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
and if i change layout_gravity to center or other value, it'll get unresolved reference: ActivityMainBinding in MainActivity
am i not supposed to use property on root layout?
so i switched to dataBinding instead of viewBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
}
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
...

DataBindingUtil.setContentView(this, layoutId) is null

binding = DataBindingUtil.setContentView(this, layoutId);
But the binding is null.
This sometimes has a value, other times null.
The activity:
public class WellcomeActivity extends Activity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WellcomeBinding binding = DataBindingUtil.setContentView(this, R.layout.wellcome);
vvv = (ViewFlipper) findViewById(R.id.main_vf);
}
}
vvv can be found; WellcomeBinding can be found; binding is null.
My English is not very good.
请多担待 Please pay more attention
XML file no error
It is an old project
Compile no error
it has a RuntimeException only.
The xml like this:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<!--<data>-->
<!--<variable-->
<!--name="vm"-->
<!--type="com.aaron.lazy.base.activity.BaseViewModel"></variable>-->
<!--</data>-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/launcher_default">
<ViewFlipper
android:id="#+id/main_vf"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="向右滑动3次以上"
android:textColor="#color/white"
android:textSize="30dp" />
</RelativeLayout>
</layout>
Have you tried using:
WellcomeBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.wellcome, null, false);
setContentView(binding.getRoot());
This is how you do it:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
Double check that you have databinding enabled in your build.gradle
android {
buildFeatures {
dataBinding true
}
}
Especially in libraries this is easily forgotten. Remember that all modules that depend on a library using databinding needs to enable it (even if that module doesn't use databinding itself)!

Categories

Resources