I'm new to android and kotlin development and I am having trouble with my first application.
I am looking to edit my TextView on button click but the compiler is complaining about an unresolved reference.
Here is my activity_main.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=".MainActivity">
<Button
android:id="#+id/click_me"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onTap"
android:text="Click me"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="64dp"
android:text="Not clicked..."
app:layout_constraintStart_toStartOf="#+id/click_me"
app:layout_constraintTop_toBottomOf="#+id/click_me" />
</androidx.constraintlayout.widget.ConstraintLayout>
and here is my MainActivity.kt file
package com.example.helloworld
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
//Method will be called on button click
fun onTap(view: View) {
textView.text = "Clicked"
}
}
}
you should define the textview as variable and then you could change it
val textView = findViewById(R.id.text_view_id)
textView.setText("string").toString()
val textViewValue = textView.text
As other user already commented, you should use view binding.
On your app Gradle script.
android {
...
buildFeatures {
viewBinding = true
}
}
Then on your MainActivity
private lateinit var binding: ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.yourButtonID.setOnClickListener {buttonTtapped()}
}
fun buttonTtapped() {
binding.yourTextViewID.text = "Clicked"
}
}
Something like this
you need to apply this in your build.gradle file
plugins {
id 'kotlin-android-extensions'}
and press sync now
then back to your MainActivity it will suggest u to import that view
Kotlin has a feature Say goodbye to findViewById refered for Kotlin Android Extensions. You need to import the import kotlinx.android.synthetic.main.activity_main.* so that you directly use the ID name of the view directly.
To get this work you need to add this plugin in the module-level build.gradle file
apply plugin: 'kotlin-android-extensions'
Another approach by findViewById
class SampleActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun onTap(view: View){
val myTextView = findViewById<TextView>(R.id.textView)
myTextView.text = "absc"
}
}
Related
I'm creating an application that displays a webview and has a button that opens the Android settings. My problem is that when I add this button, the webview stops working and only show a white screen that doesn't charge. What am I doing wrong? I leave the code below:
PD: If I delete the code starting from "//init code" it works....
MainActivity.kt
package com.becas.apn_mexico
import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.view.View
import com.becas.apn_mexico.base.BaseActivity
import com.becas.apn_mexico.databinding.ActivityMainBinding
import com.google.android.material.floatingactionbutton.FloatingActionButton
class MainActivity : BaseActivity<ActivityMainBinding>() {
companion object {
private const val URL_LINK_WEBSITE = "https://apn.tutorialez.net/index.php/landing-page/"
}
override fun setupViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater)
}
override fun setupViewModel() {
}
override fun setupUI(savedInstanceState: Bundle?) {
binding.mainWebview.loadUrlExt(URL_LINK_WEBSITE)
showAdBanner(binding.adsView.adsPhoneTabSpecialSmartBanner)
showAdInterstitial(getString(R.string.admob_interstitial))
}
// Init Code
private lateinit var fab: FloatingActionButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fab = findViewById(R.id.abrir_configuracion)
// Configurando el setonclicklistener
fab.setOnClickListener(View.OnClickListener{
val i = Intent(Settings.ACTION_APN_SETTINGS)
startActivity(i) })
}
}
ActivityMain.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.becas.apn_mexico.MainActivity">
<WebView
android:id="#+id/main_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/ads_view" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/abrir_configuracion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginRight="10dp"
android:layout_alignParentRight="true"
android:layout_above="#id/ads_view"
android:clickable="true"
android:backgroundTint="#color/colorPrimary"
android:contentDescription="#string/open_config_apn"
app:srcCompat="#drawable/ic_baseline_settings_24" />
<include
android:id="#+id/ads_view"
layout="#layout/ads_phone_tab_special_smart_banner" />
</RelativeLayout>
I think your problem is that you are not using the viewbinding to inflate your view:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// You need to get here the binding and put it into the ContentView method
val view = binding.root
setContentView(view)
fab = findViewById(R.id.abrir_configuracion)
// Configurando el setonclicklistener
fab.setOnClickListener(View.OnClickListener{
val i = Intent(Settings.ACTION_APN_SETTINGS)
startActivity(i) })
}
Alternatively, the problem is in your layout. Can you remove the
<include
android:id="#+id/ads_view"
layout="#layout/ads_phone_tab_special_smart_banner" />
From your layout and let me know if you get the expected result?
I am New to Android . I don't know how to get the data of EditText in Android .
Here is my Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity2">
<EditText
android:id="#+id/edOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:id="#+id/edSecond"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Here is my code :
val one=edOne.text.toString()
btnAdd.setOnClickListener{
val two=edOne.text.toString()
Log.e("Tag",one +" "+two)
}
one is calling from onCreate() method . and at the time of creation of you onCreate() you don't have any data in editText one .So you can't get any data from one if you have not added from xml .
So just move your one code into click listener.
val one=edOne.text.toString()
btnAdd.setOnClickListener{
val two=edOne.text.toString()
Log.e("Tag",one +" "+two)
}
You can access related View elements with findViewById and use them later.
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
class MainActivity : AppCompatActivity() {
private lateinit var edOne : EditText
private lateinit var btnAdd : Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
edOne = findViewById(R.id.edOne)
btnAdd = findViewById(R.id.btnAdd)
val one=edOne.text.toString()
btnAdd.setOnClickListener {
val two=edOne.text.toString()
Log.e("Tag",one +" "+two)
}
}
}
I'm getting compilation errors when trying to add onClickListener for a Button in my Android application. The error is as below:
build failed 792 ms
Run build 690 ms
Load build 2 ms
Configure build 94 ms
Calculate task graph 41 ms
Run tasks 550 ms
null
/home/avinash/AndroidStudioProjects/JustJava
app/src/main/java
com/example/android/justjava/MainActivity.kt
Expecting member declaration
Expecting member declaration
Expecting member declaration
Expecting member declaration
Function declaration must have a name
Task :app:buildInfoGeneratorDebug
MainActivity.kt is as below:
package com.example.android.justjava
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
val order_button = findViewById<Button>(R.id.order_button)
//set listener
order_button.setOnClickListener {
//Action perform when the user clicks on the button.
Toast.makeText(this#MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
}
}
XML is as below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Quantity"
android:textAllCaps="true"
android:layout_marginBottom="16dp"
android:paddingLeft="16dp"
android:paddingTop="16dp"/>
<TextView
android:id="#+id/quantity_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#000000"
android:textSize="16sp"
android:paddingLeft="16dp"/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Order"
android:layout_marginTop="16dp"
android:id="#+id/order_button"/>
Since your already using Kotlin, how about trying the More Kotlin style?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnLabel.setOnClickListener { Toast.makeText(this, "Toast", Toast.LENGTH_SHORT).show() }
}
You don't need findViewById() or anything else.
You'll need to import something like import kotlinx.android.synthetic.main.activity_main.*
but AndroidStudio can auto generate that for you.
Update your MainActivity like this
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle ? ) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val order_button = findViewById<Button> (R.id.order_button)
//set listener
order_button.setOnClickListener {
//Action perform when the user clicks on the button.
Toast.makeText(this #MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
}
}
}
I keep getting the binding error when trying to use the #BindingAdapter. Try for 3 days and follow numerous online articles on this subject, but still getting the below error.
#BindingAdapter("focusableColor")
fun setFocusableColor(v:CardView, color:Int) {
println("hello")
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding:ActivityMainBinding =
DataBindingUtil.setContentView(this,R.layout.activity_main)
etc...
}
In current_task_layout.xml
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="task" type="com.edenhan.simplytask.Task">
</variable>
</data>
<android.support.v7.widget.CardView
android:id="#+id/card_view">
.....
focusableColor="#{1}"/>
Error encountered:
Found data binding errors.
****/ data binding error ****msg:Cannot find the setter for attribute ‘focusableColor’ with parameter type int on
android.support.v7.widget.CardView.
file:D:\…….\app\src\main\res\layout\current_task_layout.xml
Have you tried moving the binding out of the companion object?
You should put it in a kotlin file and make it a top level function. For example:
Bindings.kt
#BindingAdapter("focusableColor")
fun setFocusableColor(v:CardView, color:Int) {..}
And put the binding xml in the app namespace
Also, see Kotlin custom attribute databinding
edit: full example
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
#BindingAdapter("focusableColor")
fun setColor(card: CardView, #ColorInt color: Int) {
// or whatever
card.setBackgroundColor(color)
}
activity_main.xml
<?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"
>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.CardView
android:id="#+id/card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:focusableColor="#{1}"/>
</android.support.constraint.ConstraintLayout>
</layout>
Below defined full code for load image using BindingAdapter with Kotlin
ImageLoader.kt
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import androidx.databinding.ObservableField
class ImageLoader {
val imageResource = ObservableField(R.drawable.ic_launcher_background)
companion object {
#JvmStatic
#BindingAdapter("android:src")
fun setImage(imageView: ImageView, imageRes: Int) {
imageView.setImageResource(imageRes)
}
}
}
activity_home.xml
<?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">
<data>
<variable name="imageLoader" type="com.sample.testdemo.ImageLoader"/>
</data>
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:src="#{imageLoader.imageResource}"
android:layout_centerInParent="true"/>
</RelativeLayout>
</layout>
HomeActivity.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.sample.testdemo.databinding.ActivityHomeBinding
class HomeActivity : AppCompatActivity() {
lateinit var binding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_home)
binding.imageLoader = ImageLoader()
}
}
Note: Don't forget to add below line at the top of app level build.gradle
apply plugin: 'kotlin-kapt'
I have started from the very basic level in Android and have created a simple app to display Happy Birthday. But the App keeps crashing in both the Emulator and the Actual hardware(SAMSUNG NOTE 8).
Need help on how can i resolve the error.
Here is xml Code :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.example.android.happybirthday.MainActivity">
<TextView
android:id="#+id/sample_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_margin="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
MainActivity Code :
package com.example.android.happybirthday
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Example of a call to a native method
sample_text.text = stringFromJNI()
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
external fun stringFromJNI(): String
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
}
You forget to typecast your TextView :
Try with below code :
val sample_text : TextView = findViewById<TextView>(R.id.sample_text) as TextView
Full Code :
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sample_text : TextView = findViewById<TextView>(R.id.sample_text) as TextView
sample_text .text = "Happy Birthday"
}
}