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
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
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:
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
Similar logic is applied to the
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.
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!