android kotlin - app keep keeps stopping when i click the button - android

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
}

Related

Changing text value with Kotlin in Android Studio

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"/>

String Reversal Program, Kotlin

I've recently decided to start learning Kotlin, and I've started a mini project to create a program that outputs a user inputted string, but in reverse.
I've built a version that uses Typed Array to store a user given string, then reverses each word within that array before returning the string but in reverse. Currently it doesn't work as intended, when the program is run, it doesn't crash and I have no error logs, but the program output looks like: [Ljava.lang.string;#2d112c3. The output I'd be expecting would be, for example: user given string: Hello World, program output: olleH dlroW. I've had a look around online and seen a few other programs of a similar nature but I so far, have been unable to fix the issues in my version.
acitivty_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">
<Button
android:id="#+id/useButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="158dp"
android:layout_marginEnd="159dp"
android:layout_marginBottom="275dp"
android:text="Reverse String"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="#+id/userInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="240dp"
android:layout_marginEnd="101dp"
android:ems="10"
android:hint="Enter a Word or String"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/programOutput"
android:layout_width="210dp"
android:layout_height="42dp"
android:layout_marginStart="100dp"
android:layout_marginTop="41dp"
android:layout_marginEnd="101dp"
android:layout_marginBottom="40dp"
android:text=""
app:layout_constraintBottom_toTopOf="#+id/useButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/userInput" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
#file:Suppress("UNUSED_CHANGED_VALUE")
package com.example.stringreversal
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val userString = findViewById<EditText>(R.id.userInput)
val submitButton = findViewById<Button>(R.id.useButton)
val changeText = findViewById<TextView>(R.id.programOutput)
submitButton.setOnClickListener {
val getString = userString.text
val typedArray: Array<String> = getString.split(" ").toTypedArray()
val count = typedArray.count()
var nul: Int = 0
while (nul <= count) {
for (word in typedArray) {
word.reversed()
}
nul++ }
val reverseString = typedArray.toString()
changeText.text = reverseString
}
}
}
I think you should use typedArray.joinToString(" ") instead of typedArray.toString()
change
val getString = userString.text
to
val getString = userString.text.toString()
userString.text returns an object of Editable type. To get string value from EditText you have call toString() from Editable object.

Why my code is not saving data using shared preferences?

I try to save the state of a Number Text View but is not working. At first I was thinking that the app was not reading my data because I copy the code from the oficial documentation. But after investigate a little more I look in android/data/ and there was not a folder called sad.whyIsNot.Saving, I tried many tutorials on youtube but I do not know why I am doing wrong. Can some one of you guys explain to me what is happening and how can I solve it?
This is the code for my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
tools:context=".MainActivity" >
<TextView
android:id="#+id/vplayeras1"
android:layout_width="45dp"
android:layout_height="30dp"
android:layout_gravity="center_horizontal"
android:text="#string/valorDefectoVeces"
android:textSize="24sp" />
<Button
android:id="#+id/agrega1"
android:layout_width="149dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/playera1" />
</LinearLayout>
And this is the code of my MainActivity.
package sad.whyIsNot.Saving
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadData()
val btnPlayera1: Button = findViewById(R.id.agrega1)
btnPlayera1.setOnClickListener{aumenta1()}
}
private fun loadData(){
val sharedPref = getPreferences(Context.MODE_PRIVATE)
val valPlayera1 = sharedPref.getInt("VECES_PLAYERA1", 0)
}
private fun aumenta1() {
val resultText: TextView = findViewById(R.id.vplayeras1)
val resultInt = resultText.text.toString().toInt() + 1
resultText.text = resultInt.toString()
val sharedPref = getPreferences(Context.MODE_PRIVATE) ?: return
with (sharedPref.edit()) {
putInt("VECES_PLAYERA1", resultInt)
commit()
}
Toast.makeText(this,"Se ha guardado!", Toast.LENGTH_LONG).show()
}
}
I don't see anything wrong with your code, I assume you know that loadData doesn't do anything with the data and you already tested if you have access to it?
Accessing the preferences outside of MainActivity might not work because getPreferences is bound to a specific activity.
If aumenta1 doesn't return I doubt that the value isn't put inside of the File, so I'd rather check if resultInt isn't 0 and that loadData really can't access the value

Android Kotlin cannot change a text string within a function

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

Android Button setOnClickListener call function to change button image

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

Categories

Resources