different between call view by name or use binding in android - android

i'am a newest in android kotlin
I want to know what is the difference between the two lines of code below and which one is better to use
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMaindinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bindins = DataBindingutil.setContentview( this, R.layout.activity_main)
textview.text="text"//or
binding.textview.text="text"
}}

TL;DR There are a few ways of getting views - using view binding is the currently recommended method.
View Binding (recommended)
The recommended way of accessing views is to use view binding. It offers a few advantages over getting the views manually
Less boilerplate code (you don't need to write a bunch of findViewById calls)
Null safety (catches errors like trying to access views from the wrong layout at build time instead of run time)
Type safety - the type of each view is set to help avoid invalid casts
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
// or, without using DataBindingUtil
// binding = ActivityMainBinding.inflate(layoutInflater)
// setContentView(binding.root)
binding.textview.text="text"
}
}
Manually Getting Views
The old way also still works - you can always call findViewById yourself. Keep in mind that it may error or return null if the view is not found or if you try to cast it to the wrong type.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textview = findViewById<TextView>(R.id.textview)
textview.text="text"
}
}
Kotlin Synthetics (deprecated)
Kotlin synthetics were introduced in 2017 to make it easier to get views, but are now deprecated and should be replaced with view binding. With synthetics you would have an import with your layout file name, then you could just access views from it directly.
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textview.text="text"
}
}

Related

How does the BINDING variable identifies the correct XML for my Android APP Screen using Java and Kotlin?

My questions is relatively simple: How does the binding find the layout to my Main Actvity since I don't use the ID, I use the name "root". And how am I going to find different layouts to my other screens using the similar code?
MAIN ACTIVITY
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater) // variable binding to access layout views
setContentView(binding.root) // here define o XML
}
}
I'm new to view binding. I haven't found a good resource to study it yet.
The ActivityMainBinding is not named ActivityMainBinding because you use it in the MainActivity. It's generated based on a layout file that is named activity_main so technically you are using specific ID but not via layout resource.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
is exactly the same as:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
without the utility of data binding ofc.
Once you have a layout that uses data binding structure, the binding is automatically generated. e.g. for layout activity_second there will be ActivitySecondBinding.

Android Development: Koltin -> How do you use the id name you created in xml and call it in activity without creating a new varaiable

I am following this tutorial video
In the activity.xml I created a toolbar with the id name
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar_excerise_activity"
android:background="#color/white"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize">
Then in the mainActivity.kt in the on create method they just call the +id name without defining the variable. How is that done?
class ExceriseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_excerise)
setSupportActionBar(**toolbar_exercise_activity**)
}
}
So some how they just called toolbar_excerise_activity id name without defiing the variable. How is that done
I would suggest using view binding for this.
https://developer.android.com/topic/libraries/view-binding#activities
private lateinit var binding: ActivityExceriseBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityExceriseBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
setSupportActionBar(binding.toolBar)
}
view binding will create a binding class for all of your xml layouts.
The binding class name depends on the file name ex:
my_layout.xml will result in a MyLayoutBinding class being created.
Also in the xml anything with an id will then exist in the binding class.
The binding will have the camel case versions of the ids names in the xml.
meaning #+id/my_id will create a myId variable in the binding class

Android access view binding val outside onCreate activity

I have an activity that has a button. On the button click I want to update text in text view.
I want to use ViewBinding instead of the normal findViewById
This is how I created the val binding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater);
setContentView(binding.root)
binding.btnRoll.setOnClickListener {
rollDice()
}
}
Now in rollDice I want to update the text view but I'm not able to access binding which make sense because its scope is limited to onCreate() , so what is the best practice for this?
private fun rollDice() {
val random = Random().nextInt(6) + 1
binding.txt_random.setText("random")
}
You have two options.
1. Store in a property
Since the inflated content of Activity is fully bound to it's lifecycle, it's safe to keep the reference as a property
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater);
setContentView(binding.root)
binding.btnRoll.setOnClickListener {
rollDice()
}
}
private fun rollDice() {
val random = Random().nextInt(6) + 1
binding.txt_random.setText("random")
}
}
2. Pass the binding to the methods
That's what I usually do, it avoids creating a property where it's not really a necessity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater);
setContentView(binding.root)
binding.btnRoll.setOnClickListener {
rollDice(binding)
}
}
private fun rollDice(binding: ActivityMainBinding) {
val random = Random().nextInt(6) + 1
binding.txt_random.setText("random")
}
}
Both options are valid ways to make the binding visible to Activities methods.
Store the binding in an instance variable on the Activity. Then you have access to it from all the methods in the Activity.
As the question has accepted answer and it is already addressed but here is my approach to the viewBinding
class MainActivity : AppCompatActivity() {
private val binding by lazy{
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.btnRoll.setOnClickListener {
rollDice()
}
}
private fun rollDice() {
val random = Random().nextInt(6) + 1
binding.txt_random.setText("random")
}
}
I go with lazy initialization of binding so that way it is only intitialized if it is required.
More you can read about lazy initialization here
https://www.baeldung.com/kotlin/lazy-initialization

Using View Binding displays blank white screen

I was experimenting View Binding in my new app. Suddenly today when I run the app it displays blank white screen instead of UI. If I remove binding and use setContentView, it works!
Any idea why this is happening?
Code:
build.gradle
viewBinding {
enabled = true
}
MainActivity
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
}
You need to call setContentView with ViewBinding as:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) // add this
}

How to initialize ViewBinding?

How to initialize VievBinding? In AppCompactActivity version 1.0.0, it became possible to pass a layout to the parent constructor so that you would not write OnCreateView.
I do so, but then I want to use VievBinding, but it doesn’t work for me. Text is not displayed. What can be done?
class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onStart() {
super.onStart()
var binding = ActivityMainBinding.inflate(layoutInflater)
binding.hello.text = "Hello"
}
}
class MainActivity : AppCompatActivity(R.layout.activity_main) {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.bind(findViewById(Window.ID_ANDROID_CONTENT).getChildAt(0))
}
Although it's easier if you rely on __Binding.inflate().
class MainActivity : AppCompatActivity {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater, R.layout.activity_main)
setContentView(binding.root)
}
Layout inflation should not be in onStart. It goes in onCreate in Activity, and onCreateView in Fragment.
// Activity class
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
val binding:YourActivityLayoutBinding =
DataBindingUtil.setContentView(this, R.layout.your_activity_layout);
}
Layout views in xml should be surrounded by <layout> tag
<layout>
...// your activity view layout
</layout>
var binding = ActivityMainBinding.inflate(layoutInflater)
This will inflate the layout again and you will get a different instance of the views than what is already set in the activity
Try using the below code to bind the activity view to the binder. Where ROOT_VIEW_ID is view id of root view in your layout
var binding = ActivityMainBinding.bind(findViewById(ROOT_VIEW_ID))*
*binding.hello.text = "Hello"

Categories

Resources