cascade
cascade builds nested popup menus with smooth height animations. It is designed to be a drop-in replacement for PopupMenu so using it in your project is beautifully only a word away. Try out the sample app to see it in action.
implementation "me.saket.cascade:cascade:1.3.0"
- val popup = PopupMenu(context, anchor)
+ val popup = CascadePopupMenu(context, anchor)
popup.inflate(R.menu.nicolas_cage_movies)
popup.show()
Use as Toolbar's overflow menu
toolbar.overrideAllPopupMenus { context, anchor ->
CascadePopupMenu(context, anchor)
}
// The lambda can be collapsed into a reference
// if you're only using the two-param constructor.
toolbar.overrideAllPopupMenus(with = ::CascadePopupMenu)
Customization
cascade
is great for apps that prefer applying dynamic themes at runtime, which PopupMenu
makes it extremely hard to do so. By providing a CascadePopupMenu.Styler
object, you can adjust colors, spacings and text styles from Kotlin (example).
CascadePopupMenu(context, anchor, styler = CascadePopupMenu.Styler(...))
By default, cascade
will pick up values from your theme in the same way as PopupMenu
would.
<style name="AppTheme">
<item name="popupMenuStyle">@style/PopupMenuStyle</item>
<item name="colorControlNormal">@color/menu_icon_color</item>
<item name="android:textColorPrimary">@color/menu_item_text_color</item>
<item name="android:textColorSecondary">@color/menu_title_text_color</item>
</style>
<style name="PopupMenuStyle" parent="@style/Widget.AppCompat.PopupMenu">
<item name="android:popupBackground">...</item>
<item name="android:popupElevation">...</item>
</style>
Navigation
For sub-menus, cascade
will automatically navigate to the parent menu when the title is clicked. For manual navigation, CascadePopupMenu#navigateBack()
or CascadeBackNavigator can be used.
popup.menu.addSubMenu("Remove").also {
it.setHeaderTitle("Are you sure?")
it.add("Burn them all")
it.add("Take me back").setOnMenuItemClickListener {
popup.navigateBack()
}
}
Custom layouts
cascade
was originally inspired by Google Drive's menu that uses a variety of complex controls. For apps that want to create something similar, a batteries-included CascadePopupWindow is provided for use with custom layouts.
val popup = CascadePopupWindow(context)
popup.contentView.addView(CustomMenuView(context)) // Also see contentView.goBack().
popup.show(anchor)