New to Kotlin, I've followed the guide on how to set up a basic "Press the button and it changes text" However Whenever I press the button, the app crashes and in the debugger I get
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)'
on a null object reference at com.example.myapplication.MainActivity.One(MainActivity.kt:16)
Here is my current MainActivity.KT:
package com.example.myapplication
import androidx.appcompat.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)
}
fun One(view: android.view.View) {
val onetext = view.findViewById<TextView>(R.id.textView)
onetext.text = "Hello"
}
}
And my activity_main.xml:
<?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">
<TextView
android:id="#+id/textView"
android:layout_width="168dp"
android:layout_height="90dp"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="One"
android:text="Button"
tools:layout_editor_absoluteX="163dp"
tools:layout_editor_absoluteY="462dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Thank you!
The problem is onetext is null, which means view.findViewById<TextView>(R.id.textView) didn't find a view with textView as id inside of view. The view passed in the function is the button, which has no textView as a child. You need to search for the textView in a view higher in the hierarchy.
In the specific example, one way of doing that is by omitting the view receiver, like so:
package com.example.myapplication
import androidx.appcompat.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)
}
fun One(view: android.view.View) {
val onetext = findViewById<TextView>(R.id.textView)
onetext.text = "Hello"
}
}
This way it will search for the textView id in the Activity's view, which is the activity_main layout.
I believe the problem has already been solved, but I noticed that in the xml file the button is not properly docked, putting:
app:layout_constraintTop_toBottomOf="#id/textView"
the button would be below the TextView component and putting:
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
the button would be centered on the screen...
Button code would look like this
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="One"
android:text="Button"
app:layout_constraintTop_toBottomOf="#id/textView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
Related
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">
<app.rive.runtime.kotlin.RiveAnimationView
android:id="#+id/animationView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:riveResource="#raw/loading_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
Kotlin file
package com.example.basicriveapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.startup.AppInitializer
import app.rive.runtime.kotlin.RiveAnimationView
import app.rive.runtime.kotlin.RiveInitializer
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
AppInitializer.getInstance(this)
.initializeComponent(RiveInitializer::class.java);
var animationView = findViewById<RiveAnimationView>(R.id.animationView);
animationView.pause();
}
}
Since I am trying to pause the Animation, it is not working and Can you please explain how to use play() and stop() methods with RiveAnimationView
You need to specify the animation name you want to play/pause inside the parentheses:
animationView.pause("animation name");
animationView.play("animation name");
You can get the animation name from the rive editor under the panel called "Animations"
I have some really simple Kotlin code for changing a text string within a function generated from a button press, but it does not work. I have a single button and two text strings, one the button press the first text string changes but the text string within the function does not change.
I am sure the problem is with the function call and not passing the right information about the activity, but just cannot work out what is wrong.
MainActivty.kt
package com.example.sandpit9
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*
import org.w3c.dom.Text
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imageButton1.setOnClickListener {v: View -> toast(v) }
imageButton1.setOnClickListener {
imageButton1.setImageResource(R.drawable.greenbutton)
textView1.text = "1234"
}
}
public fun toast(v: View) {
v.textView2.text = "1234"
}
}
MainActivty.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/imageButton1"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:textSize="34sp"/>
<TextView
android:text="textvar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView2"
android:textSize="34sp"
android:layout_marginTop="108dp"
app:layout_constraintTop_toBottomOf="#+id/imageButton1"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp"
app:layout_constraintHorizontal_bias="0.535"/>
<ImageButton
android:layout_width="174dp"
android:layout_height="154dp"
app:srcCompat="#drawable/download"
android:id="#+id/imageButton1"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.542"
app:layout_constraintVertical_bias="0.187"/>
</android.support.constraint.ConstraintLayout>
You're overwriting the click listener. The OnClickListener is a single property - not a list.
imageButton1.setOnClickListener {v: View ->
toast(v)
imageButton1.setImageResource(R.drawable.greenbutton)
textView1.text = "1234"
}
imageButton1.setOnClickListener {v: View -> toast(v) }
imageButton1.setOnClickListener {
imageButton1.setImageResource(R.drawable.greenbutton)
textView1.text = "1234"
}
Problem: ImageButton have only one OnClickListener to listen the event when there is a click event on it own. You can set the listener by using setOnClickListener. Because in your code, you use setOnClickListener two times, so the second one will override the first one.
Solution: Change your code to
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imageButton1.setOnClickListener {
imageButton1.setImageResource(R.drawable.greenbutton)
textView1.text = "1234"
textView2.text = "1234"
}
}
}
Many thanks, how simple is the solution many thanks for all the help, the setOnClickListener is setup only once to trigger the function. This is the finial code that works
package com.example.sandpit9
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*
import org.w3c.dom.Text
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imageButton1.setOnClickListener{v: View -> toast(v)}
}
private fun toast(v: View) {
imageButton1.setImageResource(R.drawable.greenbutton)
textView1.text = "1234"
textView2.text = "1234"
}
}
remove this import
import kotlinx.android.synthetic.main.activity_main.view.*
Hope this will work
I have an app with multiple buttons and the image will change depending on different requirements and variables. But, I cannot get the image button change to work within the function. The setOnClickListner will setup the function call and within the function will change the image within the button.
How do I change the image in the button?
MainActivity.kt
package com.example.sandpit9
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)
imageButton1.setOnClickListener() { changeimageelement1(R.drawable.button) }
imageButton2.setOnClickListener() { changeimageelement2(R.drawable.button) }
}
}
private fun changeimageelement1(imageButtonX: Int) {
imageButton1.setImageResource(R.drawable.greenbutton)
}
MainActivity.xml
<?xml version="1.0" encoding="utf-8">
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<ImageButton
android:layout_width="174dp"
android:layout_height="154dp" app:srcCompat="#drawable/download"
android:id="#+id/imageButton1"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp" android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginTop="8dp" app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent"/> .
</android.support.constraint.ConstraintLayout>
you should not use the () after setOnClickListener, just use
button.setOnClickLisener{
//your actions go here
}
ClickListener method should besetOnClickListener not setOnClickListener
A sample code:
button.setOnClickListener{
counter++
textView.text = "Click counter : $counter"
}
Check this tutorial
I start doing a simple android app for practice to calculate the age with Kotlin programming language, when i click the button the app, can someone help me with this and fix it to know where is my wrong because I am just very beginner
package com.calcult.age.agecalcult
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var ageInput = ageText.text.toString()
doIT.setOnClickListener{
var currentYear = Calendar.getInstance().get(Calendar.YEAR)
var getAge = currentYear-ageInput.toInt()
Toast.makeText(this, getAge, Toast.LENGTH_LONG)
}
}
}
XML FILE :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="148dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="148dp"
android:id="#+id/doIT"
android:text="#string/button_text1"
android:textSize="18sp"
app:layout_constraintHorizontal_bias="0.0" android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.771"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/ageText" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="215dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="85dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="84dp"
android:layout_marginBottom="250dp" app:layout_constraintBottom_toTopOf="#+id/doIT"/>
</android.support.constraint.ConstraintLayout>
As Vladyslav Matviienko said you're trying to get the text onCreate, what you need to do is something like this:
//Here the view is already created, so you'll be able to setup everything you need.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListener()
}
//If you are learning, you should consider reading a bit about clean code,
//it's always nice that a function does just one job, that's why I broke the code
//below in two little functions. Have in mind, this code is not the best, but at the
//moment i don't have much time to write this.
private fun setupListener() {
doIT.setOnClickListener{
//Always be aware of the type of the variables, when i wrote the first answer i was
//trying to do a math operatiton using a string, so it would not work. =P
var currentYear = Calendar.getInstance().get(Calendar.YEAR)
var getAge = (currentYear-getAge().toInt()).toString()
Toast.makeText(this, getAge, Toast.LENGTH_LONG).show()
}
}
private fun getAge(): String {
return ageText.text.toString
}
I am using the new kotlin extension for view binding but I am having this annoying warning red underline message custom_button.setOnClickListener{} stating "Overload resolution ambiguity.."
I am trying to use my custom button class which extends Button class.
My activity class
package com.example.myapplication
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)
custom_button.setOnClickListener { }
}
}
Custom button class
package com.example.myapplication
import android.content.Context
import android.widget.Button
class CustomButton(context: Context?) : Button(context)
XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<com.example.myapplication.CustomButton
android:id="#+id/custom_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>