how to set error on Editext using databinding - android

I want to show error on the Edittext, if input is not correct. I am doing this on the click of the button inside my activity class. Right now I am not getting anything, Please show me what is the correct way to achieve this.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<variable
name="activity" type="com.example.SigninActivity" />
</data>
<RelativeLayout
<EditText
android:id="#+id/ed_login"
android:layout_width="match_parent
android:layout_height="match_parent"
android:digits="0123456789"
app:errorText='#{activity.errorMsg != null ? activity.errorMsg : ""}'/>
Binding Adapter
#BindingAdapter("errorText")
fun setError(editText: EditText, str: String?) {
if(!str.isNullOrEmpty()) {
editText.
setError((HtmlCompat.fromHtml(
"<font color='red'>" + str + "</font>",
HtmlCompat.FROM_HTML_MODE_LEGACY)))
}
}
Activity class
var errorMsg: MutableLiveData<String> = MutableLiveData()
override fun onClick(view: View) {
val mobileNo = dataBinding.etLoginMobnum.text.toString()
if (!TextUtils.isEmpty(mobileNo) && mobileNo.length != 11) {
errorMsg.value = "Enter Valid Number"
}

to show an error on your EditText you may use TextInputEditText within TextInputLayout, like the following
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/textInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Your number" />
</com.google.android.material.textfield.TextInputLayout>
with app:errorEnabled="true" in the TextInputLayout you can achieve what you want
Using it in code:
show error to the user
myBinding.textInputLayout.setError("Enter Valid Number")
to remove it
myBinding.textInputLayout.setError(null)
to use it with databinding you can do the following
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable name="myData" type="com.example.CustomDataObject"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true"
android:errorText="#{myData.errorMsg}">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/textInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Your number" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>
</layout>
Binding Adapter
#BindingAdapter({"android:errorText"})
fun setError(tInputLayout: TextInputLayout, str: String) {
if (!str.isNullOrEmpty()) {
tInputLayout.setError("Enter Valid Number")
} else {
tInputLayout.setError(null)
}
}
In Activity
myBinding.setMyData(myDataObject)
note: in <data> scope in the XML you should declare your data objects with <variable> tag, not your activities.
make sure you are using material library in your gradle
implementation 'com.google.android.material:material:1.1.0'
Take a look here for more information about DataBinding

Related

Android Custom View Two Way binding not working with LiveData

I have a problem regarding livedata in custom views in android, I have a custom class with a text livedata that is two-way binded to the xml but the problem is that whenever the user writes any new value in the TextInputEditText the value of livedata is not changed.
class MaterialTextInput #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : MaterialCardView(context, attrs) {
val viewModel = MaterialTextInputViewModel()
init {
ViewMaterialTextInputBinding.inflate(
LayoutInflater.from(context), this, true
).apply {
viewModel = this#MaterialTextInput.viewModel
}
}
class MaterialTextInputViewModel : ViewModel() {
var text = MutableLiveData("")
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.app.utils.views.MaterialTextInput.MaterialTextInputViewModel" />
</data>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
app:strokeColor="#{viewModel.text.length() > 0 ? #color/color_4 : #color/white}"
app:strokeWidth="1dp">
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/email_address"
app:boxBackgroundColor="#color/white"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/textField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="1"
android:text="#={viewModel.text}" />
</com.google.android.material.textfield.TextInputLayout>
</com.google.android.material.card.MaterialCardView>
</layout>

Styling AutocompleteSupportFragment using Kotlin

I'm trying to change the style of my AutocompleteSupportFragment field
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/llSearchHolder"
android:padding="7dp">
<fragment android:id="#+id/autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:hint="#string/Iam_going_to"
/>
</LinearLayout>
I tried implementing answers on this page but I will always get Caused by: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.EditText error. I'm using Kotlin, so my code looks like below:
val autocompleteFragment = supportFragmentManager.findFragmentById(R.id.autocomplete_fragment) as AutocompleteSupportFragment?
autocompleteFragment!!.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));
((autocompleteFragment.getView()!!.findViewById(R.id.autocomplete_fragment)) as EditText).textSize = 30.0f
You need to use below code
((autocompleteFragment.getView()!!.findViewById(R.id.places_autocomplete_search_input)) as EditText).textSize = 30.0f
or more Kotlin way,
autocompleteFragment.view?.findViewById<EditText>(R.id.places_autocomplete_search_input)?.textSize = 30.0f
The correct id of EditText is places_autocomplete_search_input not autocomplete_fragment
Analysis of the problem
You are using Fragment com.google.android.libraries.places.widget.AutocompleteSupportFragment in your xml
While looking into the code of AutocompleteSupportFragment Fragment, you can see it uses layout places_autocomplete_fragment.xml. Code below
public class AutocompleteSupportFragment extends Fragment {
....
public AutocompleteSupportFragment() {
super(layout.places_autocomplete_fragment);
....
}
}
Now, if you look into places_autocomplete_fragment.xml, you can see id of EditText is places_autocomplete_search_input, code below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:layoutDirection="locale"
android:orientation="vertical"
android:textDirection="locale">
<ImageButton
android:id="#+id/places_autocomplete_search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:background="#null"
android:contentDescription="#string/places_autocomplete_search_hint"
android:padding="#dimen/places_autocomplete_button_padding"
android:src="#drawable/quantum_ic_search_grey600_24" />
<EditText
android:id="#+id/places_autocomplete_search_input"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:focusable="false"
android:focusableInTouchMode="false"
android:hint="#string/places_autocomplete_search_hint"
android:inputType="textNoSuggestions"
android:lines="1"
android:maxLines="1"
android:paddingLeft="#dimen/places_autocomplete_search_input_padding"
android:paddingRight="#dimen/places_autocomplete_search_input_padding"
android:singleLine="true"
android:textColor="#color/places_autocomplete_search_text"
android:textColorHint="#color/places_autocomplete_search_hint"
android:textSize="#dimen/places_autocomplete_search_input_text" />
<ImageButton
android:id="#+id/places_autocomplete_clear_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:background="#null"
android:contentDescription="#string/places_autocomplete_clear_button"
android:padding="#dimen/places_autocomplete_button_padding"
android:src="#drawable/quantum_ic_clear_grey600_24" />
</LinearLayout>
Android might suggest to Replace the <fragment> tag with FragmentContainerView. in your xml file. That breaks custom styling, so keep using <fragment>:
Use this:
<fragment
android:id="#+id/hostAutocompleteFrag"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Don't use this:
<androidx.fragment.app.FragmentContainerView
android:id="#+id/hostAutocompleteFrag"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Here's my AutocompleteSupportFragment init method for your reference:
private fun initAutoComplete() {
val mapAutocomplete = childFragmentManager.findFragmentById(R.id.hostAutocompleteFrag)
autoCompFrag = mapAutocomplete as AutocompleteSupportFragment
val hintTxt = autoCompFrag?.findViewById<EditText>(R.id.places_autocomplete_search_input)
hintTxt?.textSize = 15f
hintTxt?.setTextColor(requireContext().getColor(R.color.greyColor))
autoCompFrag.setHint(getString(R.string.search_hint))
autoCompFrag.setPlaceFields(listOf(Place.Field.NAME, Place.Field.LAT_LNG, Place.Field.ADDRESS))
autoCompFrag.setOnPlaceSelectedListener(object : PlaceSelectionListener {
override fun onPlaceSelected(place: Place) {
val latLng = place.latLng ?: return
setMapLocation(latLng.latitude, latLng.longitude)
}
override fun onError(status: Status) {
Log.e("$TAG initAutoComplete --- ", "An error occurred: $status")
}
})
}
For changing the EditText color in kotlin
val autocompleteFragment = supportFragmentManager.findFragmentById(R.id.autocompleteFragment) as AutocompleteSupportFragment?
autocompleteFragment.view?.findViewById<EditText>(places_autocomplete_search_input)?.setTextColor(ContextCompat.getColor(context, R.color.colorWhite));
if still not able to change then try to set the color in values as
<color name="places_autocomplete_search_text">#707070</color>
the key is important places_autocomplete_search_text

Kotlin android. binding not update data

Good evening! I try to use binding in kotlin, but data aren't update. All compile and work, but when user change text and click bsave -> i try to return data from textEdit, and data is not updated. TextEdit contains old data. In java it is working, but in kotlin i have problem. Can you help me?
It is my method onCreate, here i create model and binding its.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this,R.layout.activity_fblogin)
auth = FirebaseAuth.getInstance()
setContentView(R.layout.activity_fblogin)
user = User("Test02", "123456")
binding?.setVariable(BR.user, user)
binding?.executePendingBindings()
loginButton.setOnClickListener{_ -> loginToSystem()}
signIn.setOnClickListener{_ -> showSignInActivity()}
}
private fun loginToSystem() {
binding?.executePendingBindings()
//showProgressDialog()
val email = binding?.userName?.text.toString().trim()
val password = binding?.userPass?.text.toString()
val email2 = user?.login
val password2 = user?.password
if (!checkValidateForm(email, password)) {
return
}
It is main part of my xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="user"
type="com.example.darkt.makeyouself.models.User"
/>
</data>
<android.support.constraint.ConstraintLayout
android:descendantFocusability="beforeDescendants"
android:fitsSystemWindows="true"
android:focusableInTouchMode="true"
tools:context="com.example.darkt.makeyouself.activities.FBLogin"
tools:ignore="MissingConstraints">
<EditText
android:id="#+id/userName"
android:layout_width="220dp"
android:layout_height="43dp"
android:ems="10"
android:inputType="textPersonName"
android:text="#{user.login}"
app:layout_constraintBottom_toBottomOf="#+id/author"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Login"/>
<EditText
android:id="#+id/userPass"
android:layout_width="220dp"
android:layout_height="45dp"
android:layout_marginTop="25dp"
android:ems="10"
android:inputType="textPassword"
android:text="#{user.password}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/userName"
tools:layout_editor_absoluteX="74dp"
tools:layout_editor_absoluteY="245dp"
tools:text="Password"/>
<Button
android:id="#+id/signIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="#color/green_main"
android:text="SignIn"
android:textColor="#color/white"
app:layout_constraintStart_toStartOf="#+id/userPass"
app:layout_constraintTop_toBottomOf="#+id/userPass" />
</android.support.constraint.ConstraintLayout>
</layout>
And my short model:
data class User (val login: String, val password: String)
How i can refresh data in binding after user changes?
I was find error! My mistake is duplicating setContentView:
binding = DataBindingUtil.setContentView(this, R.layout.activity_fblogin)
....
setContentView(R.layout.activity_fblogin)
When i was delete the second setContentView, i fixed my problem

MVVM notify View about loading state

I’m using LiveData by Google now and they recomend to use a MVVM patter design. For some of my requests I use RxJava2, and listen for responses in SubscribeWith(…).
For example, when I press a button to send some data to the remote data source, I’m showing some loading animation and want to hide it onComplete() event (inside subscribeWith(…)). The problem is that I don’t have an access to the View from ModelView. How it’s possible to let the View know that loading animation should be hidden?
My current idea is to create in interface inside ViewModel and implement it in View. But it ruins the concept of View and ViewModel separation.
Well you can use liveData for this :D
At your ViewModel class you can create a live data object like this
MutableLiveData<Boolean> isLoading = new MutableLiveData<>();
and for example make a function called downloadFinished and call it in the onComplete
for your remote code
private void downloadFinished() {
isLoading.setValue(true);
}
At your activity that use the view model you observe the value of the loading and hide the progress or what ever you want
TestViewModel viewModel = ViewModelProviders.of(this).get(TestViewModel.class);
viewModel.isLoading.observe(this, new Observer<Boolean>() {
#Override
public void onChanged(#Nullable Boolean isLoading) {
if (isLoading != null) {
if (isLoading) {
// hide your progress bar
}
}
}
});
you can use DataBinding for that too
make a separate layout to reuse it everywhere
laoding_state_xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="#+id/progressBar2"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
then include it inside your desired layout
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.blogspot.soyamr.notforgotagain.view.signin.SignInViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.signin.SignInFragment">
<include
android:id="#+id/include"
layout="#layout/toolbar_application"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/signInButtonView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="68dp"
android:layout_marginEnd="16dp"
android:onClick="#{() -> viewModel.logIn()}"
android:text="#string/sign_in"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/passwordTextInputLayout" />
<TextView
android:id="#+id/noAccountTextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginEnd="4dp"
android:text="#string/no_account"
android:textColor="#android:color/black"
app:layout_constraintEnd_toStartOf="#+id/createAccountTextView"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/signInButtonView" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/emailTextInputLayout"
style="#style/myTextInputLayoutStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="80dp"
android:layout_marginEnd="16dp"
app:errorEnabled="true"
app:errorText="#{viewModel.emailErrorMessage}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/include">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/email"
android:inputType="textEmailAddress"
android:text="#={viewModel.emailText}" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/passwordTextInputLayout"
style="#style/myTextInputLayoutStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
app:errorText="#{viewModel.passwordErrorMessage}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/emailTextInputLayout">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/password"
android:inputType="textPassword"
android:text="#={viewModel.passwordText}" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="#+id/createAccountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:text="#string/create_one"
android:textColor="#color/textBlue"
app:layout_constraintBottom_toBottomOf="#+id/noAccountTextview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/noAccountTextview"
app:layout_constraintTop_toTopOf="#+id/noAccountTextview" />
<!-- **here is the important include**-->
<include
android:id="#+id/here_must_be_id_or_no_databinding"
android:visibility="#{viewModel.isLoading ? View.VISIBLE : View.GONE}"
layout="#layout/loading_state" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
i included the whole XML for clarification.
then in your view model add this
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
// Override ViewModelProvider.NewInstanceFactory to create the ViewModel (VM).
class SignInViewModelFactory(private val repository: NoteRepository) :
ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T = SignInViewModel(repository) as T
}
class SignInViewModel(val repository: NoteRepository) : ViewModel() {
private val _isLoading = MutableLiveData(true)
val emailText = MutableLiveData("")
val passwordText = MutableLiveData("")
val isLoading: LiveData<Boolean> = _isLoading
fun logIn() {
//start loading, this will make the view start loading directly
_isLoading.value = true
if (isValidInput()) {
val res = repository.logIn(LoginUser(emailText.value!!, passwordText.value!!))
}//remove loading view
_isLoading.value = false
}
//code ..
}
notice that you are observing isLoading variable inside the XML so whenever its value is changed the view will observe the change and start act on it.

databinding with RecyclerView where each item CheckBox

I have RecyclerView ,where each item represents, CheckBox and EditText
when clicks on CheckBox the text of EditText should strike through,
I have ObservableBoolean which is article.complete
I used it in app:checkBoxChangeListener="#{article.complete}"
app:itemComplete="#{article.complete}"
it works unless I scroll RecyclerView, then clicking on CheckBox another item’s text is strike through
#BindingAdapter("itemComplete")
public static void bindItemComplete(EditText itemInput, boolean complete){
itemInput.setPaintFlags(complete ?
(itemInput.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG) : 0);
}
Article.java
public class Article{
public final ObservableBoolean complete = new ObservableBoolean();
}
xml file :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="se.ica.handla.articles.ArticleListViewModel" />
<variable
name="article"
type="se.ica.handla.models.articles.Article" />
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:itemComplete="#{article.complete}"
/>
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="#={article.complete}" />
</android.support.constraint.ConstraintLayout>
</layout>
As written in my comments, I recommend you to use Two-way-Databinding.
You can completely delete this BindingAdapter:
#BindingAdapter(value = {"checkBoxChangeListener", "article"}, requireAll = false)
public static void bindCheckBox(CheckBox view, final ObservableBoolean checked, Article article) {
if (view.getTag(R.id.binded) == null) {
//Here you are setting the attributes to your *view* and
//decouple it from your article. It does not reference it,
//the properties (isChecked) isnow on the view.
//So when your view gets recycled when you scroll,
//it still has the property you set the last time -
//and not from your current article, which is displayed now in the view.
view.setTag(R.id.binded, true);
view.setOnCheckedChangeListener((buttonView, isChecked) -> checked.set(isChecked));}
}
}
As you already found out, your xml should look like this now, using Two-Way Databinding:
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:itemComplete="#{article.complete}"
/>
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="#={article.complete}" //#={} for Two-Way Databinding
/>

Categories

Resources