Realm changing values from edittext - android

I have the following problem:
For my current Android app project I'm using Realm as a database and im trying to update a string value every time my a certain textfield changes with the value thats been given to the textview. Problem is though, whenever the value of the object gets changed, the value of the textfield buggs out with previously set characters and changes back. The item that I change is also inside my viewholder. Any ideas?
Heres my code
The layout
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/entry_detail_form_8_til_text_field_container"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:hintEnabled="true"
app:layout_constraintTop_toBottomOf="#id/entry_detail_form_8_title"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<EditText
android:id="#+id/entry_detail_form_8_et_text_field"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
style="#style/Widget.MaterialComponents.TextInputEditText.OutlinedBox"/>
</com.google.android.material.textfield.TextInputLayout>
and the logic
holder.etTextArea?.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) {
realm.executeTransaction {
holder.fieldObject?.value = p0.toString()
}
}
})
Edit: The following actions did not solve the problem:
Extracting the change realm object logic into a callback outside the adapter
Moving the logic into afterTextChanged

Fixed it by disabling autoUpdate in Adapter of my RecyclerView, seems like somehow the value of my edit text was connected with the field i was changing with the new text

Related

How to validate EditText input in custom view

I'm trying to make a custom view of an EditText with a TextView under it which says the error of the validation.
My idea is to make a validation of min and max length in my custom view and make visible or change text the TextView if the edittext input passes this validations or not, but I'm new at custom views and don't have any idea of how to reach it. I didn't find any EditText custom view like this.
Can someone help me?
#1 if you want only limit your edit text
get in your layout and set android:maxLength="5"
<EditText
android:id="#+id/you_ed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:maxLength="5"
/>
#2 if you want check edit text with onClicklistener
button.setOnClickListener {
if (binding.youEd.text.length>5){
Toast.makeText(this, "error The input text is more than 5", Toast.LENGTH_SHORT).show()
}else{
//Execute the code if the input is correct
}
}
#3 If you want to check the input text momentarily (entry of each character from the user)
you_ed.addTextChangedListener(object :TextWatcher{
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(text: Editable?) {
if (text!!.length>5){
Toast.makeText(this#IndexActivity, "error The input text is more than 5", Toast.LENGTH_SHORT).show()
}else{
//Execute the code if the input is correct
}
}
})

How to use Inverse Binding Adapter in Kotlin for converting Lowercase text to Uppercase?

I am creating an android application where I want to use a feature in which a text that we have entered into an editText field can be converted into uppercase at runtime in that particular editText field only.
I have tried with this code
editText.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) {
this.text.toString().uppercase()
}
})
But it can be easily done by the concept of Inverse Binding Adapter in android. I have tried to implement it with reference of
https://developer.android.com/reference/android/databinding/InverseBindingAdapter
It is not working for me in my project. Can You explain me with step by step explanation?
Yess This Method of addTextChangedListener is available but we have to implement this method for each and every Edittext we want to convert to Upper case. So you heard correct about the InverseBinding Adapter. In InverserBinding Adapter we have to create this method for one time and you can use it any number of time.
I have implemented this using BindingAdapter and InverseBinding Adapter.In one Kotlin File, Write this two functions as follows.
Function Code
#BindingAdapter(value = ["setText", "custom:AttrChanged"], requireAll = false)
fun EditText.updateText(text: String?, listener: InverseBindingListener) {
if (this.text.toString() != text) {
this.setText(text)
}
this.doOnTextChanged { _: CharSequence?, _: Int?, _: Int?, _: Int? ->
listener.onChange()
}
}
#InverseBindingAdapter(attribute = "setText", event = "custom:AttrChanged")
fun EditText.getUpdatedText(): String? {
return this.text.toString().uppercase()
}
For Upper Case I have created one uppercase variable of MutableLiveData of type String
var uppercase = MutableLiveData("")
Now in XML i have set that property as follow:
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/edit_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="30dp"
setText="#={viewModels.uppercase}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/btn_login_data_binding" />

How can I change the background color of an EditText when text is entered using Kotlin in Android Studio?

Just to be clear, I want to change the color of the textField to be clear once text is entered and for it to go back to its old color, which in my case is gray when it has no text. I looked through stackoverflow and found some answers, however it was in Java and I am still a beginner with Kotlin, but I am writing this in Kotlin for my work.
Essentially, I want to know how can you change the background of the textField once text is entered?
I want to have the background color of that to change once text is entered using Kotlin.
This is my XML EditText that I am referring to:
<EditText
android:id="#+id/description"
android:layout_width="350dp"
android:layout_height="200dp"
android:layout_below="#id/addImage"
android:layout_alignBottom="#id/addImage"
android:layout_marginStart="50dp"
android:layout_marginTop="125dp"
android:layout_marginEnd="50dp"
android:layout_marginBottom="75dp"
android:background="#color/lightGray"
android:gravity="center"
android:hint="#string/description"
android:inputType="text"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Where do I go from here now?
class PostActivity : AppCompatActivity() {
private lateinit var button: Button
private lateinit var imageView: ImageView
private lateinit var editText: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_post)
editText = findViewById(R.id.description)
}
}
This is just what I have on my activity. I don't have any method really on how to do this.
Add a TextWatcher to react when text has been changed.
val originalColor = (editText.background as ColorDrawable).color // or Color.LIGHT_GRAY
val haveTextColor = Color.TRANSPARENT // or whatever you want
editText.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) {
editText.setBackgroundColor(if (s.isEmpty()) originalColor else haveTextColor)
}
})
You can use the doAfterTextChanged Kotlin extension function here. It can be used to perform some action every time the text changes.
editText.doAfterTextChanged { text ->
editText.setBackgroundColor(if (text.isEmpty()) color1 else color2) // Choose whatever colors you want
}

How to make a proper binding adapter for 2 way data binding in Android

I am attempting to make a page in my Android app that allows the user to enter a Float value in an EditText and binds that value to my view model. Here is my code for my current binding adapter:
import android.text.SpannableStringBuilder
import android.widget.EditText
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
#BindingAdapter("android:text")
fun setText(view: EditText, value: Float?) {
view.text = value?.let { SpannableStringBuilder(value.toString()) } ?: SpannableStringBuilder("")
}
#InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
fun getTextString(view: EditText): Float? {
val editTextString: String? = view.text?.toString()
return if(editTextString == null || editTextString == "") 0.0f else editTextString.toString().toFloat()
}
Here is the code that I have for my EditText in my layout file:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/amount_edit_text_outer"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="#dimen/edit_text_width"
android:layout_height="#dimen/edit_text_height"
android:layout_gravity="center"
android:hint="#string/edit_text_hint"
app:layout_constraintBottom_toTopOf="#+id/fab"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/amount_edit_text_inner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#={viewmodel.liveAmount$app_debug}"
android:inputType="numberDecimal" />
</com.google.android.material.textfield.TextInputLayout>
Finally, my view model live data variable looks like this:
internal val liveAmount = MutableLiveData<Float>(0.0f)
I should also add that when I run this code on my phone, it allows me to enter the first number in the EditText and nothing else. Furthermore, the keyboard does not go away unless I kill the app. Any questions or comments are welcome. Thank you all for any help!
Try changing this:
#InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
to:
#InverseBindingAdapter(attribute = "android:text")
And add this other method:
// This notifies the data binding system that the attribute value has changed.
#BindingAdapter("android:textAttrChanged")
fun setTextChangedListener(editText: TextInputEditText, listener: InverseBindingListener) {
editText.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?) {
listener.onChange()
}
})
}
This is not tested, but it should work or at least be close. See here for other similar examples:
https://github.com/gavingt/upcoming-games/blob/adc8b7e67b1e05d7bc9ac6247b82cfa93a43a26f/app/src/main/java/com/gavinsappcreations/upcominggames/utilities/BindingAdapters.kt#L324

TextWatcher not working in DialogFragment

I use TextInputLayout from this library:
implementation 'com.google.android.material:material:1.0.0'
I have following part in the layout:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/phoneNumberLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/phoneNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/label_phone_number"/>
</com.google.android.material.textfield.TextInputLayout>
I have Kotlin Android Extensions is enabled and I try to assign TextWatcher to phoneNumber as follows:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
phoneNumber.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
Log.e("DialogFragment", "phoneNumber::onTextChanged()")
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
Log.e("DialogFragment", "phoneNumber current text: " + s)
}
})
}
Nothing happens when I start typing , hours wasted... Any help would be appreciated.
You are adding the textwatcher in onActivityCreated which does not hold your root View. You should reference your phone(TextInputEditText) from View inflated in onCreateView or inside onViewCreated as suggested by #Miha_x64. Your code is correct though but the problem is with the view reference.

Categories

Resources