Android Databinding with LiveData - Validating multiple fields together Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Is it possible to make one LiveData of two LiveDatas?Android LiveData and DataBindingLivedata class inner members in databindingHow can I do databinding with livedata?Databind LiveData to CustomViewDatabinding not observe LiveData in ViewModelAndroid DataBinding LiveData - not notify changed in DialogFragment & BottomSheetDialogFragmentAndroid databinding and LiveData: Can't bind to value in LiveData propertyBoundService + LiveData + ViewModel best practice in new Android recommended architectureAndroid mvvm livedata and databindingEnable a button when all EditText complete
In musical terms, what properties are varied by the human voice to produce different words / syllables?
Antipodal Land Area Calculation
Why does it sometimes sound good to play a grace note as a lead in to a note in a melody?
How can I prevent/balance waiting and turtling as a response to cooldown mechanics
Does "shooting for effect" have contradictory meanings in different areas?
Tannaka duality for semisimple groups
preposition before coffee
The Nth Gryphon Number
Crossing US/Canada Border for less than 24 hours
C's equality operator on converted pointers
Sliceness of knots
Why can't I install Tomboy in Ubuntu Mate 19.04?
What does Turing mean by this statement?
What order were files/directories output in dir?
What's the point of the test set?
Drawing spherical mirrors
How to report t statistic from R
Is there public access to the Meteor Crater in Arizona?
How does Belgium enforce obligatory attendance in elections?
What does it mean that physics no longer uses mechanical models to describe phenomena?
Most bit efficient text communication method?
Random body shuffle every night—can we still function?
What initially awakened the Balrog?
Has negative voting ever been officially implemented in elections, or seriously proposed, or even studied?
Android Databinding with LiveData - Validating multiple fields together
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Is it possible to make one LiveData of two LiveDatas?Android LiveData and DataBindingLivedata class inner members in databindingHow can I do databinding with livedata?Databind LiveData to CustomViewDatabinding not observe LiveData in ViewModelAndroid DataBinding LiveData - not notify changed in DialogFragment & BottomSheetDialogFragmentAndroid databinding and LiveData: Can't bind to value in LiveData propertyBoundService + LiveData + ViewModel best practice in new Android recommended architectureAndroid mvvm livedata and databindingEnable a button when all EditText complete
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I am using two-way Databinding with LiveData inside a ViewModel to handle a sign-up form.
As fields are filled out, there are fields that need to be evaluated together for validity (as well as the overall form), and only enable the Submit button when everything is correct.
With a regular Observable
object and using @Bindable
this would be straightforward by just annotating a 'getter' function for each validation that is required and doing the necessary validation steps and return the appropriate result inside each function.
BUT I am working with LiveData. I came up with a solution using MediatoLiveData
(see basic example below), but it seems to me like there should be another, perhaps better, approach.
class RegistrationViewModel : ViewModel()
val email: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailConf: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailValid: MediatorLiveData<Boolean> = MediatorLiveData()
val emailChanged: (Any) -> Unit = cc@
//Obviously there is more validation needed but this is just an example
if (email.value != null && emailConf.value != null)
emailValid.value = email.value.isNotEmpty() && emailConf.value.isNotEmpty() && email.value == emailConf.value
return@cc
emailValid.value = false
init
emailValid.addSource(email, emailChanged)
emailValid.addSource(emailConf, emailChanged)
To tie it to the UI, for example, the enabled
property of a button or the visibility
property of a label could be bound to the emailValid
property appropriately.
android-databinding android-architecture-components android-livedata
add a comment |
I am using two-way Databinding with LiveData inside a ViewModel to handle a sign-up form.
As fields are filled out, there are fields that need to be evaluated together for validity (as well as the overall form), and only enable the Submit button when everything is correct.
With a regular Observable
object and using @Bindable
this would be straightforward by just annotating a 'getter' function for each validation that is required and doing the necessary validation steps and return the appropriate result inside each function.
BUT I am working with LiveData. I came up with a solution using MediatoLiveData
(see basic example below), but it seems to me like there should be another, perhaps better, approach.
class RegistrationViewModel : ViewModel()
val email: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailConf: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailValid: MediatorLiveData<Boolean> = MediatorLiveData()
val emailChanged: (Any) -> Unit = cc@
//Obviously there is more validation needed but this is just an example
if (email.value != null && emailConf.value != null)
emailValid.value = email.value.isNotEmpty() && emailConf.value.isNotEmpty() && email.value == emailConf.value
return@cc
emailValid.value = false
init
emailValid.addSource(email, emailChanged)
emailValid.addSource(emailConf, emailChanged)
To tie it to the UI, for example, the enabled
property of a button or the visibility
property of a label could be bound to the emailValid
property appropriately.
android-databinding android-architecture-components android-livedata
You sound like you want to "combine" multiple LiveData just like I did here.
– EpicPandaForce
Mar 11 at 16:22
Thanks, but it seems like you are doing exactly what I am doing here only with a level of abstraction. My question really was if there is another way of doing it that I was not seeing.
– RobertoCuba
Mar 16 at 22:16
In that case, "not really, no".
– EpicPandaForce
Mar 16 at 23:08
add a comment |
I am using two-way Databinding with LiveData inside a ViewModel to handle a sign-up form.
As fields are filled out, there are fields that need to be evaluated together for validity (as well as the overall form), and only enable the Submit button when everything is correct.
With a regular Observable
object and using @Bindable
this would be straightforward by just annotating a 'getter' function for each validation that is required and doing the necessary validation steps and return the appropriate result inside each function.
BUT I am working with LiveData. I came up with a solution using MediatoLiveData
(see basic example below), but it seems to me like there should be another, perhaps better, approach.
class RegistrationViewModel : ViewModel()
val email: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailConf: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailValid: MediatorLiveData<Boolean> = MediatorLiveData()
val emailChanged: (Any) -> Unit = cc@
//Obviously there is more validation needed but this is just an example
if (email.value != null && emailConf.value != null)
emailValid.value = email.value.isNotEmpty() && emailConf.value.isNotEmpty() && email.value == emailConf.value
return@cc
emailValid.value = false
init
emailValid.addSource(email, emailChanged)
emailValid.addSource(emailConf, emailChanged)
To tie it to the UI, for example, the enabled
property of a button or the visibility
property of a label could be bound to the emailValid
property appropriately.
android-databinding android-architecture-components android-livedata
I am using two-way Databinding with LiveData inside a ViewModel to handle a sign-up form.
As fields are filled out, there are fields that need to be evaluated together for validity (as well as the overall form), and only enable the Submit button when everything is correct.
With a regular Observable
object and using @Bindable
this would be straightforward by just annotating a 'getter' function for each validation that is required and doing the necessary validation steps and return the appropriate result inside each function.
BUT I am working with LiveData. I came up with a solution using MediatoLiveData
(see basic example below), but it seems to me like there should be another, perhaps better, approach.
class RegistrationViewModel : ViewModel()
val email: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailConf: MutableLiveData<String> by lazy MutableLiveData<String>()
val emailValid: MediatorLiveData<Boolean> = MediatorLiveData()
val emailChanged: (Any) -> Unit = cc@
//Obviously there is more validation needed but this is just an example
if (email.value != null && emailConf.value != null)
emailValid.value = email.value.isNotEmpty() && emailConf.value.isNotEmpty() && email.value == emailConf.value
return@cc
emailValid.value = false
init
emailValid.addSource(email, emailChanged)
emailValid.addSource(emailConf, emailChanged)
To tie it to the UI, for example, the enabled
property of a button or the visibility
property of a label could be bound to the emailValid
property appropriately.
android-databinding android-architecture-components android-livedata
android-databinding android-architecture-components android-livedata
edited Mar 16 at 22:19
RobertoCuba
asked Mar 7 at 4:05
RobertoCubaRobertoCuba
389414
389414
You sound like you want to "combine" multiple LiveData just like I did here.
– EpicPandaForce
Mar 11 at 16:22
Thanks, but it seems like you are doing exactly what I am doing here only with a level of abstraction. My question really was if there is another way of doing it that I was not seeing.
– RobertoCuba
Mar 16 at 22:16
In that case, "not really, no".
– EpicPandaForce
Mar 16 at 23:08
add a comment |
You sound like you want to "combine" multiple LiveData just like I did here.
– EpicPandaForce
Mar 11 at 16:22
Thanks, but it seems like you are doing exactly what I am doing here only with a level of abstraction. My question really was if there is another way of doing it that I was not seeing.
– RobertoCuba
Mar 16 at 22:16
In that case, "not really, no".
– EpicPandaForce
Mar 16 at 23:08
You sound like you want to "combine" multiple LiveData just like I did here.
– EpicPandaForce
Mar 11 at 16:22
You sound like you want to "combine" multiple LiveData just like I did here.
– EpicPandaForce
Mar 11 at 16:22
Thanks, but it seems like you are doing exactly what I am doing here only with a level of abstraction. My question really was if there is another way of doing it that I was not seeing.
– RobertoCuba
Mar 16 at 22:16
Thanks, but it seems like you are doing exactly what I am doing here only with a level of abstraction. My question really was if there is another way of doing it that I was not seeing.
– RobertoCuba
Mar 16 at 22:16
In that case, "not really, no".
– EpicPandaForce
Mar 16 at 23:08
In that case, "not really, no".
– EpicPandaForce
Mar 16 at 23:08
add a comment |
1 Answer
1
active
oldest
votes
Your approach is correct, but code has some design issues:
lazy
fields is used ininit
section. Field become not lazyemailValid
field can be exposed asLiveData
validation can be encapsulated in inner class, but it's not required
class RegistrationViewModel : ViewModel()
val email = MutableLiveData<String>()
val emailConf = MutableLiveData<String>()
@Suppress("UNCHECKED_CAST")
val emailValid: LiveData<Boolean> = MediatorLiveData<Boolean>().apply
val validator = Validator(::postValue)
addSource(email, validator as Observer<String>)
addSource(emailConf, validator as Observer<String>)
private inner class Validator(private val validationConsumer: (Boolean) -> Unit) : Observer<Any>
override fun onChanged(ignored: Any?)
//Obviously there is more validation needed but this is just an example
val email = email.value
val emailConf = emailConf.value
validationConsumer(when
email.isNullOrEmpty() -> false
emailConf.isNullOrEmpty() -> false
email == emailConf -> true
else -> false
)
If you require some heavy validation, you can make hidden mutable field for emailValid
and manually update it when background validation completed
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55035886%2fandroid-databinding-with-livedata-validating-multiple-fields-together%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your approach is correct, but code has some design issues:
lazy
fields is used ininit
section. Field become not lazyemailValid
field can be exposed asLiveData
validation can be encapsulated in inner class, but it's not required
class RegistrationViewModel : ViewModel()
val email = MutableLiveData<String>()
val emailConf = MutableLiveData<String>()
@Suppress("UNCHECKED_CAST")
val emailValid: LiveData<Boolean> = MediatorLiveData<Boolean>().apply
val validator = Validator(::postValue)
addSource(email, validator as Observer<String>)
addSource(emailConf, validator as Observer<String>)
private inner class Validator(private val validationConsumer: (Boolean) -> Unit) : Observer<Any>
override fun onChanged(ignored: Any?)
//Obviously there is more validation needed but this is just an example
val email = email.value
val emailConf = emailConf.value
validationConsumer(when
email.isNullOrEmpty() -> false
emailConf.isNullOrEmpty() -> false
email == emailConf -> true
else -> false
)
If you require some heavy validation, you can make hidden mutable field for emailValid
and manually update it when background validation completed
add a comment |
Your approach is correct, but code has some design issues:
lazy
fields is used ininit
section. Field become not lazyemailValid
field can be exposed asLiveData
validation can be encapsulated in inner class, but it's not required
class RegistrationViewModel : ViewModel()
val email = MutableLiveData<String>()
val emailConf = MutableLiveData<String>()
@Suppress("UNCHECKED_CAST")
val emailValid: LiveData<Boolean> = MediatorLiveData<Boolean>().apply
val validator = Validator(::postValue)
addSource(email, validator as Observer<String>)
addSource(emailConf, validator as Observer<String>)
private inner class Validator(private val validationConsumer: (Boolean) -> Unit) : Observer<Any>
override fun onChanged(ignored: Any?)
//Obviously there is more validation needed but this is just an example
val email = email.value
val emailConf = emailConf.value
validationConsumer(when
email.isNullOrEmpty() -> false
emailConf.isNullOrEmpty() -> false
email == emailConf -> true
else -> false
)
If you require some heavy validation, you can make hidden mutable field for emailValid
and manually update it when background validation completed
add a comment |
Your approach is correct, but code has some design issues:
lazy
fields is used ininit
section. Field become not lazyemailValid
field can be exposed asLiveData
validation can be encapsulated in inner class, but it's not required
class RegistrationViewModel : ViewModel()
val email = MutableLiveData<String>()
val emailConf = MutableLiveData<String>()
@Suppress("UNCHECKED_CAST")
val emailValid: LiveData<Boolean> = MediatorLiveData<Boolean>().apply
val validator = Validator(::postValue)
addSource(email, validator as Observer<String>)
addSource(emailConf, validator as Observer<String>)
private inner class Validator(private val validationConsumer: (Boolean) -> Unit) : Observer<Any>
override fun onChanged(ignored: Any?)
//Obviously there is more validation needed but this is just an example
val email = email.value
val emailConf = emailConf.value
validationConsumer(when
email.isNullOrEmpty() -> false
emailConf.isNullOrEmpty() -> false
email == emailConf -> true
else -> false
)
If you require some heavy validation, you can make hidden mutable field for emailValid
and manually update it when background validation completed
Your approach is correct, but code has some design issues:
lazy
fields is used ininit
section. Field become not lazyemailValid
field can be exposed asLiveData
validation can be encapsulated in inner class, but it's not required
class RegistrationViewModel : ViewModel()
val email = MutableLiveData<String>()
val emailConf = MutableLiveData<String>()
@Suppress("UNCHECKED_CAST")
val emailValid: LiveData<Boolean> = MediatorLiveData<Boolean>().apply
val validator = Validator(::postValue)
addSource(email, validator as Observer<String>)
addSource(emailConf, validator as Observer<String>)
private inner class Validator(private val validationConsumer: (Boolean) -> Unit) : Observer<Any>
override fun onChanged(ignored: Any?)
//Obviously there is more validation needed but this is just an example
val email = email.value
val emailConf = emailConf.value
validationConsumer(when
email.isNullOrEmpty() -> false
emailConf.isNullOrEmpty() -> false
email == emailConf -> true
else -> false
)
If you require some heavy validation, you can make hidden mutable field for emailValid
and manually update it when background validation completed
answered Mar 22 at 11:04
XIII-thXIII-th
3,30321839
3,30321839
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55035886%2fandroid-databinding-with-livedata-validating-multiple-fields-together%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You sound like you want to "combine" multiple LiveData just like I did here.
– EpicPandaForce
Mar 11 at 16:22
Thanks, but it seems like you are doing exactly what I am doing here only with a level of abstraction. My question really was if there is another way of doing it that I was not seeing.
– RobertoCuba
Mar 16 at 22:16
In that case, "not really, no".
– EpicPandaForce
Mar 16 at 23:08