How do I enable the button, when editText.isNotBlank() and checkBox.isChecked? - android

I have 2 editText fields, a checkbox and a button enabled to false. I need to enable the button when the edittext fields are not empty and the checkbox is checked.
buttonEnter.setOnClickListener {
editTextLogin.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
editLogin = editTextLogin.text.toString()
buttonEnter.isEnabled = isButtonVisible(editLogin, editPassword, checkBoxAgreement)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
editTextPassword.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
editPassword = editTextPassword.text.toString()
buttonEnter.isEnabled = isButtonVisible(editLogin, editPassword, checkBoxAgreement)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
checkBoxAgreement.setOnCheckedChangeListener { buttonView, isChecked ->
buttonEnter.isEnabled = isButtonVisible(editLogin, editPassword, checkBoxAgreement)
}
private fun isButtonVisible (a: String, b: String, c: CheckBox): Boolean {
return a.isNotBlank() && b.isNotBlank() && c.isChecked
}
What's wrong here?

Make a function:
private fun updateButtonState() {
buttonEnter.isEnabled = editLogin.isNotBlank() && editPassword.isNotBlank() && checkBoxAgreement.isChecked
}
Call it in the listeners of your text fields and check box:
editTextLogin.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
editLogin = editTextLogin.text.toString()
updateButtonState()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
editTextPassword.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
editPassword = editTextPassword.text.toString()
updateButtonState()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
checkBoxAgreement.setOnCheckedChangeListener { buttonView, isChecked ->
updateButtonState()
}

Related

Edit text real data missing when scrolling in a recycler view?

I have a recycler view of edit texts, however when scrolling my data of edit texts sometimes disappear and sometimes repeat itself in other edit texts.
I also use two functions in my adapter to get the values passed for edit texts in my case (product & price) but as I said I don't get the right values so I'm looking for your help guys.
This is my recycler view adapter:
class MyAdapter(var myList: List<ProductModelClass>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
inner class ViewHolder(val binding: ItemToAddBinding) : RecyclerView.ViewHolder(binding.root) {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = ItemToAddBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding.etProductName.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val text: String = s.toString()
myList[position].product = text
}
})
holder.binding.etPrice.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val text: String = s.toString()
myList[position].price = text
}
})
}
override fun getItemCount(): Int {
return myList.size
}
fun getProduct(): ArrayList<String>{
val productList: ArrayList<String> = ArrayList()
for(element in myList) {
productList.add(element.product)
}
return productList
}
fun getPrice(): ArrayList<String>{
val priceList: ArrayList<String> = ArrayList()
for(element in myList) {
priceList.add(element.price)
}
return priceList
}
}

Android Kotlin recyclerview with EditText

I have a recyclerview where each view contains a TextView and an EditText. The part where I am stuck is when I start typing in any of the row's EditText box, it automatically updates another row further down the list. I know this is occurring because of the whole recycling aspect of recyclerview and the same view is re-used for the rows further down. I just don't know how to implement this correctly.
class TodoAdapter(private val tasks : List<TodoItem>) : RecyclerView.Adapter<TodoAdapter.ViewHolder>() {
inner class ViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
var editText = view.findViewById<EditText>(R.id.edit_text)
init {
editText.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(s: Editable?) {
tasks[adapterPosition].task = s.toString()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.todo_item,parent,false)
return ViewHolder(view)
}
override fun getItemCount() = tasks.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = tasks[position]
holder.editText.setText(item.task)
}
}
class TodoItem(var task: String = "")
editText.addTextChangedListener(object TextWatcher() {
override fun afterTextChanged(s : Editable) {
item.textFieldValue = s.toString()
}
});
Put textChangeListener inside init block this should work
#MuhammadAhmed
Data class
class todolist(var hours: String, var task: String)
Adapter
override fun onBindViewHolder(holder: TodoAdapter.TodoViewHolder, position: Int) {
val currentItem = todo[position]
holder.todo.text = currentItem.hours
holder.task.text = currentItem.task
holder.task.addTextChangedListener(object: TextWatcher{
override fun afterTextChanged(s: Editable?) {
currentItem.task = s.toString()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
}

Multiplying 2 numbers without buttons in Kotlin TextWatcher

My aim is to automatically display the numbers entered by the user in the textView below using 2 edittext as shown below. How can I do this?Because this is crush. I would appreciate it if you explain in detail. Thanks in advance.
items3=pronumber.text.toString() // Edittext
items4=proprice.text.toString()// Edittext
pronumber.addTextChangedListener ( object:TextWatcher{
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
TODO("Not yet implemented")
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
totalprice.text= "Toplam Tutar : "+(items3.toInt()*items4.toInt()).toString() +" TL" //TextView
}
} )
proprice.addTextChangedListener ( object:TextWatcher{
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
TODO("Not yet implemented")
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
totalprice.text= "Toplam Tutar : "+(items3.toInt()*items4.toInt()).toString() +" TL" //TextView
}
} )
items5=totalprice.text.toString()
You should change your code like
items3=pronumber.text.toString() // Edittext
items4=proprice.text.toString()// Edittext
pronumber.addTextChangedListener ( object:TextWatcher{
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
val first = pronumber.text.toString()
val second = proprice.text.toString()
totalprice.text = if (first.isBlank() || second.isBlank()){
"Toplam Tutar : 0 TL"
} else {
"Toplam Tutar : ${first.toInt().times(second.toInt())} TL"
}
}
} )
proprice.addTextChangedListener ( object:TextWatcher{
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
totalprice.text = if (first.isBlank() || second.isBlank()){
"Toplam Tutar : 0 TL"
} else {
"Toplam Tutar : ${first.toInt().times(second.toInt())} TL"
}
}
} )
items5=totalprice.text.toString()

Issue with EditText's On TextChange Listener

In my Recyclerview's Adapter class, I have done something as below:
holder.mEdtDescription.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
listener.onDeleteOrDescribe(position, "" + holder.mEdtDescription.text.toString(), "describe")
}
})
holder.mIvDelete.setOnClickListener {
listener.onDeleteOrDescribe(position, "", "delete")
}
mEdtDescription is EditText.
On deleting some value from the recycler my adapter calls method onDeleteOrDescribe.
Unfortunately, At the same time onTextChanged is also calling.
How can I avoid calling onTextChanged when I am deleting soemthing?
Hope you got the point.
As per the solution, I have tried disabling textWatcher as below :
val textWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
ToastUtil.displayShortDurationToast(mContext,"called")
listener.onDeleteOrDescribe(
position,
"" + holder.mEdtDescription.text.toString(),
"describe"
)
}
}
holder.mEdtDescription.addTextChangedListener(textWatcher)
holder.mIvDelete.setOnClickListener {
//listener.onDeleteStep(position)
holder.mEdtDescription.removeTextChangedListener(textWatcher)
listener.onDeleteOrDescribe(position, "", "delete")
holder.mEdtDescription.addTextChangedListener(textWatcher)
}
But, still is calling onTextChange() :(
You could try disabling the TextWatcher temporarily:
val textWatcher : TextWatcher = object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
listener.onDeleteOrDescribe(position, holder.mEdtDescription.text.toString(), "describe")
}
}
holder.mEdtDescription.addTextChangedListener(textWatcher)
holder.mIvDelete.setOnClickListener {
holder.mEdtDescription.removeTextChangedListener(textWatcher)
listener.onDeleteOrDescribe(position, "", "delete")
holder.mEdtDescription.addTextChangedListener(textWatcher)
}

TextWatcher Isn't WorkingI'm using Android Studio Kotlin

I don't get any errors when running the code but the addTextChangedListener isn't running when I execute it. I am trying to have the continue button disabled until the user input text. When run, the continue is still enabled. Here is my code
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Button
import android.widget.EditText
class First_Name_Activity : AppCompatActivity() {
lateinit var editFirstNameText: EditText
lateinit var btnOpenActivity: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first_name)
editFirstNameText = findViewById(R.id.first_name_edit_text)
btnOpenActivity = findViewById(R.id.first_name_continue_btn)
editFirstNameText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
btnOpenActivity.isEnabled=true
}
}
btnOpenActivity.setOnClickListener {
val intent = Intent(this, Last_Name_Activity::class.java)
startActivity(intent)
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
}
}
override fun finish() {
super.finish()
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
}
}
You mentioned "When run, the continue is still enabled". Have you set the button to be disabled in the XML or through code (in the onCreate method) to be disabled when the app runs? After that, you can do:
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
btnOpenActivity.isEnabled = s?.isNotBlank() == true
}
First check edittext is empty or not then
Write below code inside textwatcher
If(s?.isEmpty()){
btnOpenActivity.isEnabled
}
You can check for empty text in edittext,
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (!s.toString().isEmpty()) {
btnOpenActivity.isEnabled=true
} else {
btnOpenActivity.isEnabled=false
}
}
Or
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (!editFirstNameText.text.toString().trim().isEmpty()) {
btnOpenActivity.isEnabled=true
} else {
btnOpenActivity.isEnabled=false
}
}
onTextChanged() may be called even when the CharSequence is empty or null. There is a very simple fix to your problem, a null and non-empty check :
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if(s != null && s.isNotEmpty()){
btnOpenActivity.isEnabled=true
}
}
Edit your code like this
editFirstNameText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
//btnOpenActivity.isEnabled==true
//Change this line to line bellow
btnOpenActivity.isEnabled==!s.toString().isEmpty()
}
})//you miss this bracket ')' in your code
Hi this will works for you...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sample_text_watcher)
btnOpenActivity.setOnClickListener(View.OnClickListener { })
editFirstNameText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (s != null) {
btnOpenActivity.isEnabled = s.trim().isNotEmpty()
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
happy_coding :)

Categories

Resources