Set Visibility When Input Happen on EditText - Kotlin - android

I'm kinda new with Kotlin but i'm trying to make my TextView visibility gone or visible based on the live input on Edit Text. Basically, When the user start to input something, i want this text to visible and when they delete until empty, this text is dissapear. I tried to fix it but i still couldn't found any good results. Anyway, thank you.
this is my code:
val Email = findViewById<EditText>(R.id.EmailBox)
val sEmail = Email.text.toString()
val Password = findViewById<EditText>(R.id.PasswordBox)
val sPassword = Password.text.toString()
val emailtext = findViewById<TextView>(R.id.EmailText)
val passwordtext = findViewById<TextView>(R.id.PasswordText)
if(sEmail.isEmpty()) {
emailtext.visibility = View.VISIBLE
} else if (sPassword.isEmpty()) {
passwordtext.visibility = View.VISIBLE
} else {return
}
}

You need to set a listener to check for text changes, rather than getting the current value of the EditText once during setup.
You can do this using the doOnTextChanged method. This would look like:
val email = findViewById<EditText>(R.id.EmailBox)
val emailtext = findViewById<TextView>(R.id.EmailText)
// This will hide "emailtext" when "email" is empty, and show
// it when it is not empty
email.doOnTextChanged { newText, _, _, _ ->
emailtext.visibility = if (newText.isNullOrEmpty()) View.INVISIBLE
else View.VISIBLE
}

Related

Formating a string from right to left for currency values

I'm working on creating a way to input an amount and format it from left to right with placeholder zeros.
For example, pressing 1 and 2 would show $0.12 pressing 3 would give $1.23. Pressing backspace would give $0.12.
Instead, I am getting $1,0002.00
binding.keypad.btnBackspace.setOnClickListener {
val text = binding.tvTotalValue.text.toString()
if(text.isNotEmpty()) {
binding.tvTotalValue.text = text.drop(1)
}
binding.tvTotalValue.text = ""
}
binding.keypad.onNumberSelected = {
processNewAmount(it.toString())
}
private fun processNewAmount(newValue: String) {
val text = binding.tvTotalValue.text.toString().plus(newValue)
val result = text.replace("[^0-9]".toRegex(), "") // remove any characters
val amount = result.toDouble()
binding.tvTotalValue.text = NumberFormat.getCurrencyInstance().format(amount)
}
What am I doing wrong?
Is there a better way to do this?
I advise keeping a property that stores the entered value without formatting. Each time a number is added, you can add it to this entered number and then format it for the screen. That will be a lot simpler than trying to move/remove existing symbols around in the String.
private var enteredNumber = ""
//...
binding.keypad.btnBackspace.setOnClickListener {
enteredNumber = enteredNumber.dropLast(1)
refreshTotal()
}
binding.keypad.onNumberSelected = {
if(!(it == 0 && enteredNumber == "0")) { // avoid multiple zeros or backspace will act unexpectedly
enteredNumber += it.toString()
refreshTotal()
}
}
//...
private fun refreshTotal() {
val amount = enteredNumber.toDouble() / 100.0
binding.tvTotalValue.text =
NumberFormat.getCurrencyInstance().format(amount)
}

EditText generate different than spelled numbers error

I'm trying to create a to-do list. first click menu item (add) and alertdialog write edittext and save but I'm trying to get editable text with alarm box but i get always same number.
number photo
i write bread but same number generate photo
here is a menu code
R.id.add -> {
val mDialogView = LayoutInflater.from(this).inflate(R.layout.dialog_add_todo, null)
AlertDialog.Builder(this).setView(mDialogView).setTitle("ADD TODO").setPositiveButton("Save"){
dialogInterface, i ->
val todoTitle = R.id.et_dialog_add.toString()
if(todoTitle.isNotEmpty()) {
val todo = Todo(todoTitle)
todoAdapter.addTodo(todo)
alert dialog:
<EditText
android:id="#+id/et_dialog_add"
android:hint="Buy a Bread"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</EditText>
here is adapters:
fun addTodo(todo: Todo) {
todos.add(todo)
notifyItemInserted(todos.size -1)
}
This is your problem:
val todoTitle = R.id.et_dialog_add.toString()
This is not how you get the text value from an EditText field. You need to first use findViewById() to get a reference to the EditText, and then you can use its text property to get what the user entered:
val todoTitleView = mDialogView.findViewById<EditText>(R.id.et_dialog_add)
val todoTitle = todoTitleView.text

Issue with custom dialog after removing Kotlin extension from the Android project

I have a custom dialog in my android project and it was working fine. After I removed kotlin extension from the project, I have modified my code as follows but there is some issue with the Views in the custom dialog. Codes etTitle.visibility = View.GONE and val newRequest = etDetail.text.toString() didn't work as I expected. It didn't hide the view etTitle and the value in the EditText etDetail is not picked also, it always returns emplty even when there is some value.
private lateinit var bindingDialogLayout: CustomDialogBinding
fun specialRequestDialog(currentRequest: String?) {
bindingDialogLayout = CustomDialogBinding.inflate(layoutInflater)
val dialogLayout = layoutInflater.inflate(R.layout.custom_dialog, null)
val etTitle = bindingDialogLayout.etTitle
val etDetail = bindingDialogLayout.etDetails
etTitle.visibility = View.GONE
etDetail.setText(currentRequest)
MaterialAlertDialogBuilder(this)
.setTitle("What is your special request?")
.setCancelable(false)
.setPositiveButton("Save") { dialog, which ->
val newRequest = etDetail.text.toString()
if (newRequest.isEmpty()) {
showErrorSnackBar("Type in if you have any special request, else hit cancel", true)
} else {
addButton.visibility = View.GONE
deleteButton.visibility = View.VISIBLE
}
}
.setNegativeButton("Cancel") { dialog, which ->
dialog?.dismiss()
}
.setView(dialogLayout)
.show()
}
You set the wrong view to the dialog.
Use this instead:
.setView(bindingDialogLayout.root)

How to click a button multiple times and change modes in an android app

I am new to Android Development. I need to build a temperature converter app which would convert Celcius to Farenheit and Farenheit to Celcius. I have used an editText for user input. There are two buttons. One button is to convert the input and the other one is the mode button which would toggle between the two modes of conversion. When I launch the app the mode is in celcius to farenheit by default. By clicking on mode button I can change the mode to farenheit to celcius scale. The problem is that when I again click on the mode button it does not return to the celcius to farenheit conversion mode. I don't know how to do it. Can someone help me in this regard?
I have set the function getset() for the convert button and function mode() for the mode button.
fun getSet(view: View)
{
val convert = findViewById<Button>(R.id.button)
convert.setOnClickListener {
if(editText.length()==0)
{
editText.setError("Enter a Value")
}
else
{
val editxt = findViewById<EditText>(R.id.editText)
val msg = editxt.text.toString()
val txtview = findViewById<TextView>(R.id.textView2).apply {
val cel = msg.toDouble()
val far = (cel*1.8)+32
text = "Result: " + far.toString()
}
}
}
}
fun mode(view: View)
{
val convert = findViewById<Button>(R.id.button)
val heading = findViewById<TextView>(R.id.textView).apply {
val caption = "Farenheit to Celcius"
text = caption
}
convert.setOnClickListener {
if(editText.length()==0)
{
editText.setError("Enter a Value")
}
else
{
val editxt = findViewById<EditText>(R.id.editText)
val msg = editxt.text.toString()
val txtview = findViewById<TextView>(R.id.textView2).apply {
val far = msg.toDouble()
val cel = (far-32)*0.5555555556
text = "Result: " + cel.toString()
}
}
}
}
You need to store the "mode" in a global variable.
create a global variable
var isModeCelsius: Boolean = true
Now inside your onCreate() method in your activity, under the setContentView(R.layout.your_layout_name) line enter the below code.
//Initialize edittext and button
val convert = findViewById<Button>(R.id.button)
val heading = findViewById<TextView>(R.id.textView)
val modeButton = findViewById<Button>(R.id.id_of_button)
val editxt = findViewById<EditText>(R.id.editText)
val showResultTextView = findViewById<TextView>(R.id.textView2)
//You only need to assign the click listener once
modeButton.setOnClickListener {
if (isModeCelsius) {
isModeCelsius = false
} else {
isModeCelsius = true
}
//Or you can simply use
//isModeCelsius=!isModeCelsius
}
convert.setOnClickListener {
val msg = editxt.text.toString()
if(isModeCelsius){
val far = msg.toDouble()
val cel = (far-32)*0.5555555556
showResultTextView.text = "Result: " + cel.toString()
}else{
val cel = msg.toDouble()
val far = (cel*1.8)+32
showResultTextView.text = "Result: " + far.toString()
}
}

Sending radio button data to next activity in Kotlin

In an android app I want to let the user check a radio button and depending on what the user checked I want it to change things in the next activity (e.g. hiding a button or change the text of a button). How am I doing this?
I already found out how to let it change a textview in the next activity, but probably there is a better way for it too.
val rg1 = findViewById<RadioGroup>(R.id.rg1)
val rb1 = findViewById<RadioButton>(R.id.rb1)
val rb2 = findViewById<RadioButton>(R.id.rb2)
val tv1 = findViewById<TextView>(R.id.tv1)
val btnNext = findViewById<Button>(R.id.btnNext)
rg1.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener { _, i ->
when (i) {
R.id.rb1 -> tv1.text = "something"
R.id.rb2 -> tv1.text = "something else"
}
})
btnNext.setOnClickListener {
val result = tv1.text.toString()
val intent = Intent(this, Activity2::class.java)
intent.putExtra("Result", result)
startActivity(intent)
}
tv1.isGone = true
After doing this in Activity2:
val result = intent.getStringExtra("Result")
val tv2 = findViewById<TextView>(R.id.tv2)
tv2.text = result
it changes tv2 in Activity2 (tv1 is only there to get the text string and shouldn't be displayed in first activity, as I said before, there is probably a better solution too).
But most important what to do when I want to hide a button or do something else in the next activity depending on radio buttons?
not sure if this is an answer to your question or not, but consider this:
you can change
rg1.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener { _, i ->
when (i) {
R.id.rb1 -> tv1.text = "something"
R.id.rb2 -> tv1.text = "something else"
}
})
to something like this
rg1.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener { _, i ->
when (i) {
R.id.rb1 -> OneSetupOfYourUI()
R.id.rb2 -> AnotherSetupOfYourUI()
}
})
then define what you want to change inside functions and call those functions, instead of changing every single component.
fun OneSetupOfYourUI(){
//change stuff in here
}
Maybe this helps ?
Then when you start the new activity :
val result = tv1.text.toString()
val intent = Intent(this, Activity2::class.java)
intent.putExtra("Result", result)
startActivity(intent)
Consider adding several intent.putExtra() statements based off of your configured UI or what the user selected
Edit
Just for anyone interested or unsure, you can also simply do this in a when statement:
when (i) {
R.id.rb1 -> {
tv1.text = "something"
etc.
//now you can do several statements here :)
}
}

Categories

Resources