Android databinding and LiveData: Can't bind to value in LiveData property










0















I'm trying out databinding for a view that's supposed to display data exposed through a LiveData property in a viewmodel, but I've found no way to bind the object inside the LiveData to the view. From the XML I only have access to the value property of the LiveData instance, but not the object inside it. Am I missing something or isn't that possible?



My ViewModel:



class TaskViewModel @Inject
internal constructor(private val taskInteractor: taskInteractor)
: ViewModel(), TaskContract.ViewModel

override val selected = MutableLiveData<Task>()
val task: LiveData<Task> = Transformations.switchMap(
selected
) item ->
taskInteractor
.getTaskLiveData(item.task.UID)

... left out for breivety ...



I'm trying to bind the values of the task object inside my view, but when trying to set the values of my task inside my view I can only do android:text="@=viewmodel.task.value". I have no access to the fields of my task object. What's the trick to extract the values of your object inside a LiveData object?



My task class:



@Entity(tableName = "tasks")
data class Task(val id: String,
val title: String,
val description: String?,
created: Date,
updated: Date,
assigned: String?)









share|improve this question
























  • why are you using two way binding for TextView

    – ABr
    Nov 16 '18 at 10:23











  • Because I want to save changes made to the task, whenever the user makes changes to the task in the UI.

    – Bohsen
    Nov 16 '18 at 13:48











  • Then you have a problem with task not being mutable in any case.

    – tynn
    Nov 16 '18 at 16:37











  • @tynn Will it only work if task is mutable?

    – Bohsen
    Nov 17 '18 at 13:01












  • you have to observe your live data variable inside fragment in order to get the changes

    – ABr
    Nov 21 '18 at 7:32















0















I'm trying out databinding for a view that's supposed to display data exposed through a LiveData property in a viewmodel, but I've found no way to bind the object inside the LiveData to the view. From the XML I only have access to the value property of the LiveData instance, but not the object inside it. Am I missing something or isn't that possible?



My ViewModel:



class TaskViewModel @Inject
internal constructor(private val taskInteractor: taskInteractor)
: ViewModel(), TaskContract.ViewModel

override val selected = MutableLiveData<Task>()
val task: LiveData<Task> = Transformations.switchMap(
selected
) item ->
taskInteractor
.getTaskLiveData(item.task.UID)

... left out for breivety ...



I'm trying to bind the values of the task object inside my view, but when trying to set the values of my task inside my view I can only do android:text="@=viewmodel.task.value". I have no access to the fields of my task object. What's the trick to extract the values of your object inside a LiveData object?



My task class:



@Entity(tableName = "tasks")
data class Task(val id: String,
val title: String,
val description: String?,
created: Date,
updated: Date,
assigned: String?)









share|improve this question
























  • why are you using two way binding for TextView

    – ABr
    Nov 16 '18 at 10:23











  • Because I want to save changes made to the task, whenever the user makes changes to the task in the UI.

    – Bohsen
    Nov 16 '18 at 13:48











  • Then you have a problem with task not being mutable in any case.

    – tynn
    Nov 16 '18 at 16:37











  • @tynn Will it only work if task is mutable?

    – Bohsen
    Nov 17 '18 at 13:01












  • you have to observe your live data variable inside fragment in order to get the changes

    – ABr
    Nov 21 '18 at 7:32













0












0








0








I'm trying out databinding for a view that's supposed to display data exposed through a LiveData property in a viewmodel, but I've found no way to bind the object inside the LiveData to the view. From the XML I only have access to the value property of the LiveData instance, but not the object inside it. Am I missing something or isn't that possible?



My ViewModel:



class TaskViewModel @Inject
internal constructor(private val taskInteractor: taskInteractor)
: ViewModel(), TaskContract.ViewModel

override val selected = MutableLiveData<Task>()
val task: LiveData<Task> = Transformations.switchMap(
selected
) item ->
taskInteractor
.getTaskLiveData(item.task.UID)

... left out for breivety ...



I'm trying to bind the values of the task object inside my view, but when trying to set the values of my task inside my view I can only do android:text="@=viewmodel.task.value". I have no access to the fields of my task object. What's the trick to extract the values of your object inside a LiveData object?



My task class:



@Entity(tableName = "tasks")
data class Task(val id: String,
val title: String,
val description: String?,
created: Date,
updated: Date,
assigned: String?)









share|improve this question
















I'm trying out databinding for a view that's supposed to display data exposed through a LiveData property in a viewmodel, but I've found no way to bind the object inside the LiveData to the view. From the XML I only have access to the value property of the LiveData instance, but not the object inside it. Am I missing something or isn't that possible?



My ViewModel:



class TaskViewModel @Inject
internal constructor(private val taskInteractor: taskInteractor)
: ViewModel(), TaskContract.ViewModel

override val selected = MutableLiveData<Task>()
val task: LiveData<Task> = Transformations.switchMap(
selected
) item ->
taskInteractor
.getTaskLiveData(item.task.UID)

... left out for breivety ...



I'm trying to bind the values of the task object inside my view, but when trying to set the values of my task inside my view I can only do android:text="@=viewmodel.task.value". I have no access to the fields of my task object. What's the trick to extract the values of your object inside a LiveData object?



My task class:



@Entity(tableName = "tasks")
data class Task(val id: String,
val title: String,
val description: String?,
created: Date,
updated: Date,
assigned: String?)






android android-databinding android-livedata android-viewmodel






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 9:51









Knossos

11.6k74172




11.6k74172










asked Nov 14 '18 at 21:18









BohsenBohsen

613625




613625












  • why are you using two way binding for TextView

    – ABr
    Nov 16 '18 at 10:23











  • Because I want to save changes made to the task, whenever the user makes changes to the task in the UI.

    – Bohsen
    Nov 16 '18 at 13:48











  • Then you have a problem with task not being mutable in any case.

    – tynn
    Nov 16 '18 at 16:37











  • @tynn Will it only work if task is mutable?

    – Bohsen
    Nov 17 '18 at 13:01












  • you have to observe your live data variable inside fragment in order to get the changes

    – ABr
    Nov 21 '18 at 7:32

















  • why are you using two way binding for TextView

    – ABr
    Nov 16 '18 at 10:23











  • Because I want to save changes made to the task, whenever the user makes changes to the task in the UI.

    – Bohsen
    Nov 16 '18 at 13:48











  • Then you have a problem with task not being mutable in any case.

    – tynn
    Nov 16 '18 at 16:37











  • @tynn Will it only work if task is mutable?

    – Bohsen
    Nov 17 '18 at 13:01












  • you have to observe your live data variable inside fragment in order to get the changes

    – ABr
    Nov 21 '18 at 7:32
















why are you using two way binding for TextView

– ABr
Nov 16 '18 at 10:23





why are you using two way binding for TextView

– ABr
Nov 16 '18 at 10:23













Because I want to save changes made to the task, whenever the user makes changes to the task in the UI.

– Bohsen
Nov 16 '18 at 13:48





Because I want to save changes made to the task, whenever the user makes changes to the task in the UI.

– Bohsen
Nov 16 '18 at 13:48













Then you have a problem with task not being mutable in any case.

– tynn
Nov 16 '18 at 16:37





Then you have a problem with task not being mutable in any case.

– tynn
Nov 16 '18 at 16:37













@tynn Will it only work if task is mutable?

– Bohsen
Nov 17 '18 at 13:01






@tynn Will it only work if task is mutable?

– Bohsen
Nov 17 '18 at 13:01














you have to observe your live data variable inside fragment in order to get the changes

– ABr
Nov 21 '18 at 7:32





you have to observe your live data variable inside fragment in order to get the changes

– ABr
Nov 21 '18 at 7:32












2 Answers
2






active

oldest

votes


















1














why are you using two way binding for TextView
android:text="@=viewmodel.task.value"
instead use like this android:text="@viewmodel.task.title"






share|improve this answer

























  • Doesn't solve my problem. Still can't access the fields of my task.

    – Bohsen
    Nov 16 '18 at 13:48






  • 1





    please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

    – ABr
    Nov 21 '18 at 7:27












  • This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

    – Bohsen
    Jan 30 at 9:06



















2














For LiveData to work with Android Data Binding, you have to set the LifecycleOwner for the binding



binding.setLifecycleOwner(this)


and use the LiveData as if it was an ObservableField



android:text="@viewmodel.task"


For this to work, Task needs to implement CharSequence. Using viewmodel.task.toString() might work as well. To implement a two-way-binding, you'd have to use MutableLiveData instead.






share|improve this answer























  • But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

    – Bohsen
    Nov 17 '18 at 12:49











  • I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

    – Bohsen
    Nov 17 '18 at 13:04












  • observe the task field for updates

    – ABr
    Nov 21 '18 at 7:37










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
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308863%2fandroid-databinding-and-livedata-cant-bind-to-value-in-livedata-property%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














why are you using two way binding for TextView
android:text="@=viewmodel.task.value"
instead use like this android:text="@viewmodel.task.title"






share|improve this answer

























  • Doesn't solve my problem. Still can't access the fields of my task.

    – Bohsen
    Nov 16 '18 at 13:48






  • 1





    please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

    – ABr
    Nov 21 '18 at 7:27












  • This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

    – Bohsen
    Jan 30 at 9:06
















1














why are you using two way binding for TextView
android:text="@=viewmodel.task.value"
instead use like this android:text="@viewmodel.task.title"






share|improve this answer

























  • Doesn't solve my problem. Still can't access the fields of my task.

    – Bohsen
    Nov 16 '18 at 13:48






  • 1





    please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

    – ABr
    Nov 21 '18 at 7:27












  • This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

    – Bohsen
    Jan 30 at 9:06














1












1








1







why are you using two way binding for TextView
android:text="@=viewmodel.task.value"
instead use like this android:text="@viewmodel.task.title"






share|improve this answer















why are you using two way binding for TextView
android:text="@=viewmodel.task.value"
instead use like this android:text="@viewmodel.task.title"







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 21 '18 at 7:32

























answered Nov 16 '18 at 10:25









ABrABr

28327




28327












  • Doesn't solve my problem. Still can't access the fields of my task.

    – Bohsen
    Nov 16 '18 at 13:48






  • 1





    please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

    – ABr
    Nov 21 '18 at 7:27












  • This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

    – Bohsen
    Jan 30 at 9:06


















  • Doesn't solve my problem. Still can't access the fields of my task.

    – Bohsen
    Nov 16 '18 at 13:48






  • 1





    please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

    – ABr
    Nov 21 '18 at 7:27












  • This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

    – Bohsen
    Jan 30 at 9:06

















Doesn't solve my problem. Still can't access the fields of my task.

– Bohsen
Nov 16 '18 at 13:48





Doesn't solve my problem. Still can't access the fields of my task.

– Bohsen
Nov 16 '18 at 13:48




1




1





please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

– ABr
Nov 21 '18 at 7:27






please use some values inside the task model instead of the whole value i.e., android:text="@viewmodel.task.title"

– ABr
Nov 21 '18 at 7:27














This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

– Bohsen
Jan 30 at 9:06






This finally worked after some tweaks. Also people should be aware that the IntelliJ code completion can create problems, as it doesn't make suggestions for the fields of the livedata object.

– Bohsen
Jan 30 at 9:06














2














For LiveData to work with Android Data Binding, you have to set the LifecycleOwner for the binding



binding.setLifecycleOwner(this)


and use the LiveData as if it was an ObservableField



android:text="@viewmodel.task"


For this to work, Task needs to implement CharSequence. Using viewmodel.task.toString() might work as well. To implement a two-way-binding, you'd have to use MutableLiveData instead.






share|improve this answer























  • But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

    – Bohsen
    Nov 17 '18 at 12:49











  • I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

    – Bohsen
    Nov 17 '18 at 13:04












  • observe the task field for updates

    – ABr
    Nov 21 '18 at 7:37















2














For LiveData to work with Android Data Binding, you have to set the LifecycleOwner for the binding



binding.setLifecycleOwner(this)


and use the LiveData as if it was an ObservableField



android:text="@viewmodel.task"


For this to work, Task needs to implement CharSequence. Using viewmodel.task.toString() might work as well. To implement a two-way-binding, you'd have to use MutableLiveData instead.






share|improve this answer























  • But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

    – Bohsen
    Nov 17 '18 at 12:49











  • I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

    – Bohsen
    Nov 17 '18 at 13:04












  • observe the task field for updates

    – ABr
    Nov 21 '18 at 7:37













2












2








2







For LiveData to work with Android Data Binding, you have to set the LifecycleOwner for the binding



binding.setLifecycleOwner(this)


and use the LiveData as if it was an ObservableField



android:text="@viewmodel.task"


For this to work, Task needs to implement CharSequence. Using viewmodel.task.toString() might work as well. To implement a two-way-binding, you'd have to use MutableLiveData instead.






share|improve this answer













For LiveData to work with Android Data Binding, you have to set the LifecycleOwner for the binding



binding.setLifecycleOwner(this)


and use the LiveData as if it was an ObservableField



android:text="@viewmodel.task"


For this to work, Task needs to implement CharSequence. Using viewmodel.task.toString() might work as well. To implement a two-way-binding, you'd have to use MutableLiveData instead.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 16 '18 at 16:43









tynntynn

20.5k54782




20.5k54782












  • But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

    – Bohsen
    Nov 17 '18 at 12:49











  • I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

    – Bohsen
    Nov 17 '18 at 13:04












  • observe the task field for updates

    – ABr
    Nov 21 '18 at 7:37

















  • But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

    – Bohsen
    Nov 17 '18 at 12:49











  • I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

    – Bohsen
    Nov 17 '18 at 13:04












  • observe the task field for updates

    – ABr
    Nov 21 '18 at 7:37
















But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

– Bohsen
Nov 17 '18 at 12:49





But Task is not just a string. Task is a full blown object with multiple properties. I understand that it's possible to bind to strings, booleans, ints etc. directly inside a LiveData, but then the viewmodel will be covered with livedata fields. I thought databinding was more mature and would be able to bind to the properties of the object inside a LiveData object. I'm going to add my Task class to my question.

– Bohsen
Nov 17 '18 at 12:49













I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

– Bohsen
Nov 17 '18 at 13:04






I already have binding.setLifecycleOwner(viewLifecycleOwner) as this is inside a fragment.

– Bohsen
Nov 17 '18 at 13:04














observe the task field for updates

– ABr
Nov 21 '18 at 7:37





observe the task field for updates

– ABr
Nov 21 '18 at 7:37

















draft saved

draft discarded
















































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.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308863%2fandroid-databinding-and-livedata-cant-bind-to-value-in-livedata-property%23new-answer', 'question_page');

);

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







這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3

Museum of Modern and Contemporary Art of Trento and Rovereto