Search code examples
androidandroid-fragmentsandroid-architecture-navigationshared-element-transition

Shared element update image source


I am using androidx navigation component. In FragmentA, I have a recycler view with cards. These cards contain an image an a like button. When the users likes the content, the like button asset changes. This card content is a separate layout which is included in the RecyclerViews.ViewHolder layout:

<MaterialCardView>
    <include layout="@layout/item_main_content_layout" />
</MaterialCardView>

and the item_layout included above:

    <merge>
        <LinearLayout
            android:id="@+id/content"
            android:transitionName="content">
            <ImageView
                android:id="@+id/image"/>
            <ImageView
                android:id="@+id/like"/>
        </LinearLayout>
    </merge>

During binding view holder in adapter I dynamically update the transitionName with unique id. FragmentB has included the same layout and on view creation I update the transition name with the item being passed on. When navigating from FragmentA -> FragmentB by clicking on a item the shared transition works as expected. When I pop back stack it falls back to its original position in the list as expected.

The problem As said earlier. When I like/dislike content, the asset of the like button changes. This asset in the like ImageView is preserved when I open FragmentB. But when I change the state, so I change the asset of the like button in FragmentB and pop back stack, the transition happens but the button asset is switched back to the starting asset in FragmentA. How can I retain the src drawable in shared element when popping back stack?


Solution

  • I have forgot to mention that FragmentA is MVI and FragmentB is MVVM. This means that FragmentA is rendered based on a view state I am reducing in its presenter. The adapter receiving the data is not tightly coupled with the fragment so it doesn't know about the data change. I have added an extra event to my presenter to update the view state when some update happens on the item in the DB. When user resumes FragmentA, it renders view state. ViewState now contains the updated item and I handle that case accordingly by passing the updated item to the adapter (similar when passing new data). Now the data of the both ViewHolders are same and when going back from FragmentB -> FragmentA my like state is persisted.