I keep getting "modifier override is not applicable to local function' when trying to use onclicklistener - android

I'm trying to write a code for a small quiz app. When you click the plus button it takes you to a separate page where you input the question and answer. When you click the check button it takes you back to the previous page and a new button with the text set as the question is created. I'm running across an error when I try to put override under my buttonclick event. Is there anyway I can get around this?
Newbtn page:
package com.example.test
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import com.google.android.material.floatingactionbutton.FloatingActionButton
class Newbtn : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_newbtn)
val newbutton = Button(this#Newbtn)
val btn = findViewById<FloatingActionButton>(R.id.btn2)
val intent = getIntent()
val test = intent.getStringExtra("test")
newbutton.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
newbutton.width=1010
newbutton.height=300
newbutton.gravity = Gravity.CENTER
newbutton.translationX= 65F
newbutton.setTextColor(Color.parseColor("#FFFFFFFF"))
newbutton.setBackgroundColor(Color.parseColor("#250A43"))
newbutton.text = test
btn.setOnClickListener{
val activityCode = 2
startActivityForResult(
Intent(this#Newbtn, QuestionPage::class.java), activityCode
)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == activityCode && resultCode == Activity.RESULT_OK) {
val buttonText = data?.getStringExtra("test")
newbutton.text = buttonText
}
}
}
}}
QuestionPage:
package com.example.test
import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import com.google.android.material.floatingactionbutton.FloatingActionButton
class QuestionPage : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_question_page)
val btn3 = findViewById<FloatingActionButton>(R.id.btn3)
val intent = Intent(this#QuestionPage, Newbtn::class.java)
val question = findViewById<EditText>(R.id.question)
val answer = findViewById<EditText>(R.id.answer)
val questiontext = question.text.toString()
val answertext = answer.text.toString()
val returnIntent = Intent()
returnIntent.putExtra("test", questiontext)
setResult(Activity.RESULT_OK, returnIntent)
finish()
btn3.setOnClickListener{
startActivity(intent)
}
}
}

Your Newbtn activity needs an onCreatefunction, and an onActivityResult one, both on the same level (inside the activity). Right now you have one nested inside the other, and inside an unclosed click listener lambda too.
Look at the vertical lines inside the IDE:
See how whenever you open a scope, like with a function or lambda, there's a vertical line going from where you open that scope to where you close it, i.e. where the closing brace is? See how btn.setOnClickListener extends way further down than where it should end? How onActivityResult is inset inside it?
You can use these guides to help you clean things up when the bracing gets messed up, and make sure stuff is nested correctly. So onActivityResult should be on the same indented level as onCreate, which should be closed before onActivityResult's opening brace - two separate lines, one after the other, each ending in a closing brace.
You can't reference activityCode because you're defining it inside the click listener lambda, it's a local variable in there, you can't see it from outside. It's not complaining in your current code because you have onActivityResult nested inside that lambda, where it can see the variable - but that code is broken because the function shouldn't be there anyway.
Just stick the activityCode value somewhere in your class, or even outside it (constants like this are a good candidate for const val ACTIVITY_CODE = 2 declarations). Basically, your onActivityResult function needs to be able to handle any result that comes in, and refer to the possible identifying codes it's supposed to handle. Those shouldn't be defined secretly in the click listener, because then the activity gets the result back and says "what does 2 mean???"

Related

Trying to find the proper file path for my app, but "context" doesn't seem to exist

I'm trying to export data from the app into a text file, and to do that I understand that I need to discover the appropriate path to my app-specific file storage spot. I discovered that I should use something like context.getExternalFilesDir(). While this seems pretty straightforward, when I try to do val path = context.getExternalFilesDir(), Android Studio tells me that context is a function and can't be called with the arguments supplied. Seems like others don't have this problem, is there an import that I'm missing or something along those lines?
Since I had come across this line context.getExternalFilesDir() to be used to return the path where files should go, I had assumed it would just work, but no such luck. I've dug into it for quite a while but can't seem to figure out what to do in the case where the IDE doesn't want to recognize it.
Here are my imports, in case there's something I'm missing:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.times
import com.example.packandfind.ui.theme.PackAndFindTheme
import java.io.File
Here's the function that contains the attempted call:
fun importData(): SnapshotStateMap<String, List<String>> {
val fileName = "data.txt"
// val path = context.getExternalFilesDir()
val file = File(fileName)
var data = mutableStateMapOf<String, List<String>>()
if (file.exists())
{
file.forEachLine {
val (key, value) = it.split("=")
// var newValue = value.replace("[", "")
// newValue = newValue.replace("]", "")
// newValue = newValue.replace(" ", "")
val listValue = value.split(",")
data[key] = listValue
}
} else {
data = mutableStateMapOf("New box" to listOf("location"))
}
return data
}
You appear to be attempting to use Compose UI. In that case, a #Composable function can use LocalContext.current to obtain a valid Context:
#Composable
fun FruitText(fruitSize: Int) {
// Get `resources` from the current value of LocalContext
val resources = LocalContext.current.resources
val fruitText = remember(resources, fruitSize) {
resources.getQuantityString(R.plurals.fruit_title, fruitSize)
}
Text(text = fruitText)
}
(from the docs)
Since you seem to be unfamiliar with Context... I strongly recommend that either:
You learn conventional Android app development (using the View-based UI system) via some book or course before taking on Compose UI, or
You find some book or course that teaches you Android app development using Compose UI
I would suggest to pass the context as a parameter from the activity you called from and make your function accept it.
fun importData(context: Context): SnapshotStateMap<String, List<String>> {
....
}

I am learning Android studio and doing a rectangle calculator, my kotlin has 19 errors and cannot figure it out

I am learning Android studio and doing a rectangle calculator. My Kotlin has 19 errors, and I cannot figure it out. I keep getting unresolved errors for btn, functions that cannot be called, and expecting an element. I am trying to do a calculator that takes height and width and then calculates area and perimeter. Just need guidance on what I am doing wrong and not looking for someone to give me new code.
MainActivity.kt
package com.example.calculator
import android.annotation.SuppressLint
import android.icu.text.DecimalFormat
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.*
class MainActivity : AppCompatActivity() {
#SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_calculate.setOnClickListener {
calculate()
btn_calculate.onEditorAction(EditorInfo.IME_ACTION_DONE)
}
btn_reset.setOnClickListener {
reset()
}
}
private fun calculate() {
val formatter = DecimalFormat("#.##")
val editNum1 = (EditText) editNum1.text.toString()
val editNum2 = (EditText) editNum2.text.toString()
val Area = DecimalFormat(editNum1.toDouble() * editNum2.toDouble())
val Perimeter = DecimalFormat(2* ( (editNum1.toDouble()) + (editNum2.toDouble()))
}}
If you want to access the views from your XML file directly in your activity you should use Kotlin Android Extension. But this plugin is deprecated. You should migrate to View Binding.
https://developer.android.com/topic/libraries/view-binding/migration

Issue in Display view dynamically code failed

I am very new to Android development and actually stuck with code in tutorial for Kotlin programming for android. The code below is not working and I have tried to find alternative but no luck.
Will appreciate if somebody can help we with the alternative code
below is a code:
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
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)
addSomeViews(count = 5)
}
fun addSomeViews(count: Int) {
for (i in 1..count) {
val textView = TextView(this)
textView.text = "Hey, learner # $i"
textView.textSize = 20f
my_layout.addView(textView)
}
val button = Button(this)
button.text = "Click me!"
my_layout.addView(button)
}
}
That kotlinx.synthetic stuff is deprecated - it doesn't work anymore. Instead of just referencing my_layout directly (the synthetics are supposed to look it up for you and create that variable) you need to find it yourself:
fun addSomeViews(count: Int) {
// lookup the layout viewgroup and create a variable for it
val my_layout = findViewById<ViewGroup>(R.layout.my_layout)
for (i in 1..count) {
val textView = TextView(this)
textView.text = "Hey, learner # $i"
textView.textSize = 20f
// now this variable exists
my_layout.addView(textView)
}
}
Aside from that... this isn't how a beginner should be learning Android imo. Creating views like this is kind of an advanced thing, mostly you never have to do it, and if you do there's a bunch of configuration you need to do on the views to make them display correctly (like the appropriate LayoutParams)
You can do it, but mostly you create your layouts in XML using the layout editor. And Compose is the new thing for writing UI in code, which is probably worth learning. It's up to you obviously, I just wanted to warn you that it's a strange thing for a beginner to be learning, and you might be better trying the Codelabs stuff instead

simple currency converter with Kotlin

i have two questions.(sorry if my questions seem simple to you but i'm new to kotlin)
The first I try to do a simple calculation with a value entered in one field which is multiplied by a defined value, to get the result in another field.
import androidx.appcompat.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)
Convertisseur.setOnClickListener {
val idr = editTextNumber.text.toString().toDouble()
val dollardft = 0.00007
resultDollar.text = (idr * dollardft).toString()
}
following this code I have an error on the result = Type mismatch: inferred type is String but Editable! was expected.
My second question, is it possible to do without a calculate button to obtain the result instantly.
thank you very much for your advice
Use setText instead
resultDollar.setText((idr * dollardft).toString())
or
fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this)
resultDollar.text = (idr * dollardft).toString().toEditable()

Button is not reacting as expected, I am trying to see if the function is not working or if there some other error

The function should use user input to do math and output into a text box for the user. On clicking the button, absolutely nothing happens. LogCat isn't showing me anything, so I'm not sure how to Troubleshoot this issue. I've got two similiar activities in the same project that are working fine, so I suspect I may not being doing the math correctly but can't find any other information. Any advice is appreciated.
package com.example.awcc
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main3.*
class Setup : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
editTextNumber120.text.toString().toInt()
}
}
class ThirdActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
val button2 = findViewById< Button >(R.id.button2)
button2.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
val button3 = findViewById< Button >(R.id.button3)
button3.setOnClickListener {
val intent2 = Intent(this, MainActivity::class.java)
startActivity(intent2)
val button7 = findViewById< Button >(R.id.button35)
button7.setOnClickListener {
var value1 = editTextNumber120.text.toString().toInt()
fun accessory(): Int {
return when {
value1 > 10 -> value1 * 0
value1 in 10..20 -> value1 * 1
value1 in 21..40 -> value1 * 2
value1 in 40..50 -> value1 * 3
value1 in 51..75 -> value1 * 4
value1 < 75 -> value1 * 5
else -> value1
}
}
val complete = accessory().toString()
try {
editTextNumber19?.setText(complete)
} catch (e: NumberFormatException) {
Toast.makeText(
applicationContext,
"Please enter a 0 in the blank field",
Toast.LENGTH_LONG
).show()
}
}
}
}
}
where is editTextNumber120 defined? what is this text being used for?
If you're expecting the value to carry over from the setup activity to activity3, that's not how it works. Each activity uses it's own data and if you need data to be shared across Activities and Fragments, then you need to create a data model for that information.
Example:
public class MyDataModel {
protected MutableLiveData<Int> editTextData;
public MyDataModel() {
editTextData = new MutableLiveData<>();
}
// setter/getter - returns a LiveData object that allows
// you to observe the value for any changes
// If you don't need to observe changes, then just keep it as an int/string
}
This way your other Activity can access the same data being used in the Setup activity. Also note, this doesn't persist across reboots, so if you want the setup to contain the previous data used in the last boot of the app, i'd look into SharedPreferences.
Also I don't know the structure of your app, but I would question why you need so many Activities? My app I'm working on is fairly robust but even I only have one activity (with a couple fragments), and another activity for the settings, and that's it.
I found the answer if anyone runs into this issue behind me. I was using Var instead of Val so it wasn't actually multiplying or changing the var at all. Changed to Val and it works like a charm!

Categories

Resources