Why does Kotlin Activity have a problem finding Buttons? - android

Attempting to update an older Android game project to use view binding. Android Studio version 4.1.3. I am thinking my problem has to do with the naming of my binding class.
the xml file is called activity_correct_guess.xml and I am using what I think is the name that gets generated by the view binding: ActivityCorrectGuessBinding. Appreciate and ideas!
The build errors:
Unresolved reference: ActivityCorrectGuessBinding
Unresolved reference: binding
Unresolved reference: binding
In the Gradle build module I have the following:
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
buildFeatures {
viewBinding = true
}
layout file: activity_correct_guess.xml
<Button
android:id="#+id/btnPlayAgain"
android:layout_width="wrap_content"
..... />
Activity file: CorrectGuessActivity.kt
class CorrectGuessActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityCorrectGuessBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
playAgain()
exitGame()
}
fun playAgain() {
binding.btnPlayAgain.setOnClickListener {
val intent = Intent("com.appkotlin2021v4.MainActivity")
startActivity(intent)
}
}

Typically, you define your view binding in the root of your Activity or Fragment or in an init block:
class CorrectGuessActivity : AppCompatActivity() {
//get to inflating!
private val binding = ActivityCorrectGuessBinding.inflate(layoutInflater)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
playAgain()
exitGame()
}
fun playAgain() {
binding.btnPlayAgain.setOnClickListener {
val intent = Intent("com.appkotlin2021v4.MainActivity")
startActivity(intent)
}
}
The only time you need to "wait to inflate" is when you're in a non-ViewGroup-based class like RecyclerView.Adapter, etc.

Yes, this is the correct way to define the view binding. thank you!

Related

How to fix error (unresolved reference: editText issue ) in android?

The kotlin-android-extensions Gradle plugin is deprecated. Please use this migration guide to start working with View Binding and the kotlin-parcelize plugin.
C:\\Users\\ADMINISTRATOR\\AndroidStudioProjects\\MyApplication4\\app\\src
\\main\\java\\com\\denizas\\myapplication\\MainActivity.kt: (14, 21):
Unresolved reference: editText
Caused by: org.gradle.api.GradleException:
Compilation error. See log for more details
build.gradle(Module:App)
android {
....
buildFeatures {
viewBinding true
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private val binding
get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityChartBinding.inflate(layoutInflater)
setContentView(R.layout.activity_main)
}
fun topla(view: View){
binding.apply {
//in this part it is used to access the views in the layout part
var sayi1 = editText.text.toStirng()
}
}
}

different between call view by name or use binding in 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"
}
}

Not able to import image id

enter image description here
Glide.with(this).load(url).into(imageView)
You can try with findViewById:
Glide.with(this).load(url).into(findViewById(R.id.imageView))
However, the best approach would be using viewBinding:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
...
Glide.with(this).load(url).into(binding.imageView)
}
}
In this case, don't forget to enable viewBinding in your app-level build.gradle file, by adding:
android {
...
buildFeatures {
viewBinding = true
}
}
For more on viewBinding check here

Kotlin / Migration to View Binding

I was following YT video to make Quiz App, but in the end I got this error with binding:
The 'kotlin-android-extensions' Gradle plugin is deprecated.
Please use this migration guide
(https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.
But when I add binding for instance to tv_name.text, i do get error that text is expecting Variable and everything the same with other binding parts.
Libraries part
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import com.example.quizapp.databinding.ActivityResultBinding
Code part
class ResultActivity : AppCompatActivity() {
private val binding by viewBinding(FragmentResultActivity::bind)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_result)
// Hide the status bar.
//window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
val userName = intent.getStringExtra(Constants.USER_NAME)
binding.tv_name.text = userName
val totalQuestions = intent.getIntExtra(Constants.TOTAL_QUESTIONS, 0)
val correctAnswers = intent.getIntExtra(Constants.CORRECT_ANSWERS, 0)
binding.tv_score.text = "Your Score is $correctAnswers out of $totalQuestions."
binding.btn_finish.setOnClickListener {
startActivity(Intent(this#ResultActivity, MainActivity::class.java))
}
}
}
You need to initialize the binding variable properly. Please use the below code:
class ResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityResultBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityResultBinding.inflate(layoutInflater)
setContentView(binding.root)
// Hide the status bar.
//window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
val userName = intent.getStringExtra(Constants.USER_NAME)
binding.tv_name.text = userName
val totalQuestions = intent.getIntExtra(Constants.TOTAL_QUESTIONS, 0)
val correctAnswers = intent.getIntExtra(Constants.CORRECT_ANSWERS, 0)
binding.tv_score.text = "Your Score is $correctAnswers out of $totalQuestions."
binding.btn_finish.setOnClickListener {
startActivity(Intent(this#ResultActivity, MainActivity::class.java))
}
}
}
Since I do not have your resources with me available, I think you might have to change the naming of ActivityResultBinding. However, I am pretty sure this is it.
Happy Coding! :)
First you need to let android know that you are using view binding. so go to "Gradle Scripts" folder and open app level build.gradle(Module:nameOfProject) file and inside android property add this:
android {
// ------ VIEW BINDING SETTING ------
// this creates the binding object
buildFeatures{
viewBinding true
}
// after set up, click on "Sync Now"
}
then in MainActivity.kt:
class MainActivity : AppCompatActivity() {
// Initialize binding object. if ActivityMainBinding is not ready in menu click "Build/Make project"
private lateinit var binding:ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// view Bindig
// binding default layout inflater
binding= ActivityResultBinding.inflate(layoutInflater)
// inflate the root views which is Linear Layout, we access with .root
setContentView(binding.root)
// Set click listeners
....
}

Why does it still say "Unresolved reference: button" even when I have button id in xml?

I have simple android app, and I want to click button to pass other activity. But it says
Unresolved reference: button
even I give id in xml. I do not know where I mistake.
Screenshot:
activity_main.xml:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:text="Click"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
main_activity:
class MainActivity : AppCompatActivity() {
companion object {
const val USER = "user"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val user = User( "mayk", "qqqq", PersonalInfo("mayk", "james"))
button.setOnClickListener{
val intent = Intent (this, Activity2::class.java)
intent.putExtra(USER, user)
startActivity(intent)
}
}
}
val button = findViewById<View>(R.id.button)
why still say “Unresolved reference: button” even I have button id in xml?
The ids in your xml layout files are not Kotlin variables. You need to declare a variable val button before you can use it. You also need to initialize the variable to refer to a Button object. One way to do that is with
val button = findViewById<View>(R.id.button)
I suggest that you read the beginner guides at https://d.android.com to understand the fundamentals of Android programming.
No need to use findViewById()
Go to your Build.Gradle (Module: app)
Add the following line
apply plugin: 'kotlin-android-extensions'
or
id 'kotlin-android-extensions'
Then it will ask you to sync
Then press sync
After it will ask you to import that only by using ALT+ENTER
UPDATE : THIS SOLUTION IS DEPRECATED
now you have to use View Binding
set the viewBinding build option to true in the module-level build.gradle file
android {
...
buildFeatures {
viewBinding true
}
}
To set up an instance of the binding class for use with an activity, perform the following steps in the activity's onCreate() method:
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
You can now use the instance of the binding class to reference any of the views:
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
For more information you can have a look at https://developer.android.com/topic/libraries/view-binding

Categories

Resources