Published April 17, 2020
In this post, the user will see a list of tweets instead of just one. There are a couple components available to achieve this. I will review the pros and cons of each, and use the best candidate to implement the feature. Along the way, I will highlight the issues I encounter and open issues I have not yet resolved.
Currently there are a couple options for displaying a list of items. The first is the
VerticalScroller. This component accepts a lambda as the last parameter to generate the children to display. The issue with this component is that it creates all of the child views at once. This works well for a small number of items but the memory performance is poor when the number grows.
dev05 release introduced the
AdapterList component. This functions similarly to the
RecyclerView, but it is easier to setup. The
AdapterList only generates the views that are currently on the screen so the performance is much better for a large number of items.
The list of tweets is represented as another composable function. To get something displaying quickly, it initially accepts a list of
Tweet objects as a parameter.
This list is passed to the
data parameter of the
AdapterList. As each item is displayed, the associated
Tweet object is passed to the
Tweet object is wrapped in a
MutableState and passed to the
In order to see the current list, a new preview function is needed. To simplify things, a generator function is created first to generate a test list of Tweets. It returns a
MutableList since the list state will need to change as the user clicks on the action row items in the separate
This generator function is used in a new preview function so the tweet list can be viewed.
After building the project, the
TweetList preview is visible in the preview pane.
Only 7 of the tweets are displayed in the preview so it must determine how many items to display based on a test screen size. Either way, it is looking good so far. One improvement is to add some padding to the
AdapterList to give it some extra space.
Seeing the list in the preview is nice but I want to see how it performs on a device. Updating the
onCreate function allows me to run it on my emulator.
With that in place, I can run the app and see the
TweetList in action. The performance right now is pretty janky but I expect it to improve quite a bit in the future.
The scrolling performance is one issue, but there is another one that is more severe. Clicking on the action row items on any of the
TweetViews no longer updates the state of the view. My first thought is that even though the
TweetView is trying to update its state, the overall state of the
AdapterList is not being changed. Since the
AdapterList’s data is not changing it is not recomposing the individual rows.
To address this, the listener functions need to be brought up to the
TweetList function instead of the
TweetView is updated to only take in a
Tweet object instead of a
MutableState as well. The
TweetList should be the only view with state since it needs to track the list of tweets as a whole.
TweetView will be simplified. The parameter is made a regular
Tweet object and the listener declarations are removed in favor of additional parameters.
TweetList is updated next to create the required listeners and pass them into the
TweetView. The index of the individual tweet is also needed in order for the listeners to update the correct place in the tweet list when the user clicks on the action row items. In order for the list to be updated, its type must be changed to
MutableList as well.
To get the project to build, the preview function for the
TweetView also requires updates to match the new parameter list.
With these updates in place, the app can build. One more step is needed. The
AdapterList needs a
MutableState parameter so it knows to recompose its child views when the list changes.
This requires updates to the
onCreate function in
MainActivity as well as updates to the preview function so the project can build.
With these updates the
AdapterList should observe any updates made to the list of tweets and update the corresponding
TweetView row accordingly. However, the
AdapterList is still not updating the individual rows. Toast messages added into the comment, like, and retweet listeners confirms that they are handling the events, but the screen is not updating. Based on my discussions with some of the folks working on Compose it seems like this is likely a bug in
AdapterList. A bug ticket has been filed for this issue so I am hopeful it will be resolved soon!
With that, a list of tweets is now visible on the screen.
AdapterList takes the performance benefits of
RecyclerView and greatly simplifies the setup.
Thanks for reading and stay tuned for more!