Published April 03, 2020
This post focuses on improving the state implementation from my previous blog post. At the end of the post the Tweet
class is mutable. The click listeners update the interaction count values as well as the like and retweet state. While this does work, I prefer to keep my classes immutable. This forces me to be explicit when the state changes, thus reducing side effects from other areas in the code.
The first goal is to make the Tweet
class immutable.
Now that the Tweet
cannot be updated by the listeners, another mechanism is needed to serve this purpose. This is where MutableState
comes in to play. The javadocs of the file state
* The [MutableState] class can be used several different ways. For example, the most basic way is to store the returned state
* value into a local immutable variable, and then set the [MutableState.value] property on it.
This object is used to store an immutable variable. In this case, the Tweet
object is wrapped by this MutableState
. To do this, first the TweetView
parameter needs to be changed to the MutableState
type.
Next, the onCreate()
and preview functions need to wrap the Tweet
object in a MutableState
. There is a mutableStateOf()
function that can accomplish this.
This function accepts the state value as the first parameter. The second is a function that determines if two states are equal. The default value of this is ReferentiallyEqual
which just determines if the two value objects have the same reference. This works for an immutable value object but if the value object can change, there is also a StructurallyEqual
option that checks if the properties of the two value objects are equal.
In this case, the ReferentiallyEqual
will be used since I will create a new Tweet
class any time the data needs to change. I can update the onCreate()
function to implement the state.
The same is needed in the preview function.
With that in place, the TweetView
function can now use the state to setup the data and listeners. First, the Tweet
is pulled out of the MutableState
using the value
property.
Accessing the value property in TweetView
subscribes it to any changes to the MutableState. When the Tweet
object changes the new data will be sent to TweetView
, which will display it.
Each of the three listeners: commentClick
, retweetToggle
, and likeToggle
need updates in order to work with the new immutable Tweet
object. The copy()
function is used heavily to modify only the necessary data. The commentClick
function is a good place to start since the logic is straightforward.
The new count value is calculated from the current Tweet
value. This new count is fed to the copy()
function to create a new Tweet
object for the updated state. Setting the new state is as simple as setting the value
on the MutableState
object.
Similar logic is applied to the retweetToggle
and likeToggle
listeners. These are slightly more complex because they decide how to modify the count based on the current toggle state.
With this in place the app should build and run successfully. It should also function the same as before. Clicking on the comment action increments the comment count, while clicking on retweet or like toggles the count up and down.
Now the Tweet
class is immutable but the state can still be changed thanks to MutableState
. This class will be a big help in projects because having immutable data classes for the state value requires more explicit changes for the state.
My next post will focus on showing a profile image for the user, which will wrap up the basic Tweet view. Further posts will show how to display a list of Tweets as well as how to show a floating action button over the list.
Thanks for reading and stay tuned for more!
Photo by Michal Czyz on Unsplash.