Implementing Favorite Event option in the Toolbar of Event Details in the Open Event Android App

The Open Event Android app allows users to favorite any Event. The users can easily see their favorited events in a section called Favorites. This blog will illustrate about how favorite event option has been implemented in the Toolbar of Event Details section of the Open Event Android app.

We will straightaway move onto the code of event_details.xml. We can clearly observe that we need to implement a menu item in the toolbar or action bar. So, to implement that, we first need to add a favorite icon in the support actionbar. To do that, we add a menu item in the event_details.xml file present under the menu folder.

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto">
  <group android:id="@+id/event_menu">
      ...
  </group>
  
  <item
      android:id="@+id/eventShare"
      android:icon="@drawable/ic_share_white_24dp"
      android:title="@string/event_share"
      app:showAsAction="always"/>

  <item
      android:id="@+id/favoriteEvent"
      android:icon="@drawable/ic_baseline_favorite_border_white_24px"
      android:title="@string/favorite_event"
      app:showAsAction="always"/>
</menu>

We can clearly observe that a menu item having an id of favoriteEvent has been added. We create a vector drawable with a heart shaped having only border. We also create a vector drawable of heart shaped filled with white colour. android:icon is set to the border icon as default.

We have made our desired changes in the xml files. Now we will head onto the code of EventDetailsViewModel. Basically, we want the user to be able to favorite the event. So we add the function setFavoriteEvent to the ViewModel.

fun setFavorite(eventId: Long, favourite: Boolean) {
compositeDisposable.add(eventService.setFavorite(eventId, favourite)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
               Timber.d("Success")
}, {
               Timber.e(it, "Error")
               error.value = "Error"
}))
}

This function utilises eventId, which is of long type and favourite, which is of Boolean type. This function makes an RxAndroid network call to set favorite as false or true to the event having the eventId. Heading onto the code in EventDetailsFragment. In the onOptionsItemSelected function, we add the favoriteEvent item case in the switch statement.

R.id.favoriteEvent -> {
eventViewModel.setFavorite(eventId, !(eventShare.favorite))
if (eventShare.favorite) {
setFavoriteIcon(R.drawable.ic_baseline_favorite_border_white_24px)
} else {
setFavoriteIcon(R.drawable.ic_baseline_favorite_white_24px)
}
return true

}

We clearly observe that we are setting the eventId and boolean fields in the .setFavorite function. There is a function called setFavoriteIcon, present in a conditional which sets the appropriate favorite icon.

Let us head onto the code of the function setFavoriteIcon

private fun setFavoriteIcon(id: Int){
menuActionBar?.findItem(R.id.favoriteEvent)?.icon = context?.let { ContextCompat.getDrawable(it, id) }
}

We observe that the code is quite straight forward, We just replace the menu item icon of id favoriteEvent with id. We add a conditional in the ViewModel observer of event. This conditional helps in setting the correct favorite image icon even after configuration changes.

eventViewModel.event.observe(this, Observer {
if (eventShare.favorite) {
setFavoriteIcon(R.drawable.ic_baseline_favorite_white_24px)
}
})

This is how we have successfully implemented a Favorite Event option in the Toolbar of EventDetailsFragment.

Additional Resources