Couldn't enable button using xml and data binding - android

I'm want to enable button when repeatPasswordInputEditText is not empty, I tried to enable it with android:enabled="#{!repeatPasswordInputEditText.text.toString().isEmpty()}" but it doesn't work, why ? I'm also calling binding.lifecycleOwner = this in onCreateView
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/uRepeatPassword"
android:layout_width="384dp"
android:layout_height="75dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:hint="#string/repeat_password_hint"
app:passwordToggleEnabled="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/uNewPassword">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/repeatPasswordInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:text="#{passwordChangeViewModel._repeatPassword}"
android:background="#color/white"
app:passwordToggleEnabled="false"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="#+id/changePasswordButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Change Password"
android:enabled="#{!repeatPasswordInputEditText.text.toString().isEmpty()}"
app:layout_constraintTop_toBottomOf="#+id/uRepeatPassword">
</com.google.android.material.button.MaterialButton>

You cannot listen to changes in EditText text inside the XML itself.
In your code, you have
android:text="#{passwordChangeViewModel._repeatPassword}"
Seems like you are trying to use two-way data-binding here where _repeatPassword is a MutableLiveData<String>. This won't work because it is just one-way right now. You need to replace # with #= to make it two way.
Now that you have two-way data binding working, you can use the value of this live data to enable/disable your button:
android:enabled="#{!_repeatPassword.empty}"
If you are not using two-way data binding, you will have to put the logic in your Activity/Fragment:
repeatPasswordInputEditText.doAfterTextChanged { text ->
changePasswordButton.enabled = text.isNotEmpty()
}

Related

Keyboard showed when focus is on AutoCompleteTextView

I don't understand what I'm doing wrong. I would like to show only dropdown menu. The result is like the photo below: I can edit on it and keyboard is showed. What I'm missing?
Aspected (without pointer enabled):
Result:
XML layout
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/gender_container"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:hint="Gender"
app:layout_constraintTop_toBottomOf="#+id/year_of_bird_container">
<AutoCompleteTextView
android:id="#+id/gender_spinner"
android:layout_width="match_parent"
android:inputType="none"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
From Fragment
private fun setAdapter() {
val genderList = mutableListOf(
Gender.MALE.toString(),
Gender.FEMALE.toString(),
Gender.OTHER.toString(),
Gender.PREFER_NOT_TO_SAY.toString()
)
val adapter = ArrayAdapter(
requireContext(), R.layout.simple_spinner_dropdown_item, genderList
)
binding.genderSpinner.setAdapter(adapter)
}
I used AutoCompleteTextView in my previous project and the usage was same. But to be sure i just created fresh project and added your code, it's working fine too.
Maybe adding android:imeOptions="actionDone" to the previous EditText might solve it, because it can be use the keyboard and when you finish with it, if it's not actionDone keyboard stays for next component.
Other than that, check about your other code parts that effect this, like onFocus or onClick events. If it is not about them i suggest you to create new project and try this again step by step to find what is causing this.
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/gender_container"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:hint="Gender"
app:layout_constraintTop_toBottomOf="#+id/year_of_bird_container">
<AutoCompleteTextView
android:id="#+id/gender_spinner"
android:layout_width="match_parent"
android:inputType="none"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
You can try this if you don't want to show the Softkeyboad but retain the cursor/caret. Put this in your activity
window.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
Screenshot showing the cursor/caret active with no SoftKeyboard
I suggest you to use spinner like below. AutoCompleteTextView not a spinner actually.
<androidx.appcompat.widget.AppCompatSpinner
android:id="#+id/spinner"
style="#style/AddressSpinnerTheme"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="5dp"
app:entries="#{viewModel.uiState.value.spinnerItemList}"
app:newValue="#{viewModel.uiState.value.spinnerSelectedItem}"
app:onItemSelected="#{listener}" />

Default text for TextInputLayout with AutoCompleteTextView

I am using this to display a Spinner type of view for TextInputLayout but I am not getting how can I set any default value to it.
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintTextColor="#color/primary_color_3">
<AutoCompleteTextView
android:id="#+id/accType_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#android:color/transparent"
android:inputType="none"
android:text="#={viewModel.mytext}"
android:lineSpacingExtra="5sp"
android:textColor="#color/name_primary_color"
android:textSize="14sp" />
</com.google.android.material.textfield.TextInputLayout>
The placeholder only works when it is in focus mode so please suggest a workaround.
Edit:
I am using two way data binding in this textview and it seems due to this no solution is working in my case. Even i try to set default value for binded object then it automatically pop ups the spinner on application launch which i don't need so please suggest me something.
The AutoCompleteTextView can work with an Adapter.
Just for example:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/til"
..>
<com.google.android.material.textfield.MaterialAutoCompleteTextView
.../>
</com.google.android.material.textfield.TextInputLayout>
Create the adapter:
ArrayList<String> items = new ArrayList<>();
items.add("Material");
items.add("Design");
items.add("Components");
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,R.layout.item, items);
TextInputLayout textInputLayout = findViewById(R.id.til);
Set the default value and the adapter:
((MaterialAutoCompleteTextView) textInputLayout.getEditText()).setAdapter(adapter);
((MaterialAutoCompleteTextView) textInputLayout.getEditText()).setText(adapter.getItem(1),false);
It is important to set the filter false in setText(...,false) to
display the entire list in dropdown and not only the single value.
Use android:text attribute on AutoCompleteTextView like this
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintTextColor="#color/primary_color_3">
<AutoCompleteTextView
android:id="#+id/accType_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select Something"
android:backgroundTint="#android:color/transparent"
android:inputType="none"
android:lineSpacingExtra="5sp"
android:textColor="#color/name_primary_color"
android:textSize="14sp" />
</com.google.android.material.textfield.TextInputLayout>

DataBinding background drawable update based on focus

I have a TextInputEditText inside a TextInputLayout.
I want to change the TextInputLayout's background based on whether the EditText has focus or not.
I can easily accomplish that by observing the edittext's focus from the activity and then update the background accordingly.
But it seems such a waste to update the element from the activity if I'm already using Data Binding.
Is there a way to reference the TextInputLayout's background from the focus change callback inside the EditText?
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/input_field_unselected_background">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:inputType="text"
android:hint="#string/hint_placeholder"
android:background="#android:color/transparent"/>
</com.google.android.material.textfield.TextInputLayout>
Yes you can, just keep in mind that you have to account for when you lose focus. It could be due to the back button, switching input fields or hitting enter on the keyboard. Since you do not know what the user will do you can account for that as discussed here based on your use case..
In your layout
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#{viewModel.hasFocus ? #drawable/background_focused : #drawable/background_unfocused}">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:inputType="text"
android:hint="#string/hint_placeholder"
android:background="#android:color/transparent"
android:onClick="#{() -> viewModel.setFocus(true)}"/>
</com.google.android.material.textfield.TextInputLayout>
A lambda is used to call the appropriate background based on the viewmodel data while onClick determines if it is in focus.
In you viewmodel (Kotlin)
val hasFocus = MutableLiveData<Boolean>().apply{postValue(false)}
fun setFocus(value: Boolean){
hasFocus.value = value
}

Two-way databinding screen orentation change changes value

I'm using two-way databinding.
I have some data inside my Room databse and depending on what user writes in edittext showing that value in textview.
When I rotate screen, value gets updated. At fist its empty string then back to how it was. I know this is normal behavior of activity lifecycle.
So I would like to know the best way to get rid of this problem.
Thanks in advance.
EditText:
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/edtOddelek"
android:text="#={viewModel.loginOddelek}"
android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/textView3"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintStart_toStartOf="#+id/edtGeslo" style="#style/adoEditTextStyle"/>
TextView:
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/txtOddelek"
android:layout_marginTop="8dp"
android:text="#{viewModel.oddelek}"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="12dp"
android:textColor="#color/orangeDark"
app:layout_constraintTop_toBottomOf="#+id/edtOddelek"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="12dp"/>
ViewModel:
val loginOddelek = NonNullMutableLiveData<String>("")
val oddelek:LiveData<String> = Transformations.switchMap(loginOddelek){
settingsModel.getSifrPr(it)
}

Can you add a textview or something similar as a child to a textinputlayout?

I have an application that uses a lot of textinputlayouts because I like the style they create
on one screen I am showing info on one object and I want it too look like the data the user entered with the textinputedittexts , small caption above and the data below
right now I have a textinputlayout with a disabled textinputedittext below
is there a way to just have a textview under the textinputlayout that will be shown in the same style?
thanks in advance for any help you can provide
edit:
as a side note here's what I am currently using to disable the edittext fully
<android.support.design.widget.TextInputLayout
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/name"
tools:text="This is where the name goes"
android:inputType="none"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false" />
what I am trying to avoid is not use clickable and inputtype etc etc in EVERY view that I'm trying to create, and instead use a single view
so other than creating a custom edittext (like NeverEnabledEditText) that starts unclickabke in every way, or add all those attributes to my xml, is there a way to do the above?
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/date_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Date"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/tv_date"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="none"
android:clickable="true"
android:focusable="false"
android:drawableEnd="#drawable/ic_keyboard_arrow_down_black_24dp"
android:paddingEnd="4dp"
android:paddingVertical="12dp"
android:drawablePadding="4dp"
android:textColor="#color/colorPrimary"
tools:text="00/00/0000" />
</com.google.android.material.textfield.TextInputLayout>
Although a TextInputEditText, now you have it acting like a textview because you can't edit it but can set text to it. You're welcome !

Categories

Resources