Android Use Sub Menu Item as Spinner/Dropdown/Combobox in AppBar

Mar 19, 2019

If you allow user to make a selection (e.g. Pending, Approved or Rejected) in AppBar to update the list in RecyclerView.

  • You can add a Spinner into Toolbar
  • Or you can use menu with sub menu items to simulate UI of a Spinner

This article will use menu with sub menu items to simulate UI of a Spinner

Create a menu with sub menus: res/menu/testlist.xml

NOTE: Use app:showAsAction="always" to ensure menu is always shown.

<?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">

    <item
        android:id="@+id/action_status"
        android:title="Status"
        app:showAsAction="always">
        <menu>
            <item
                android:id="@+id/action_status_pending"
                android:title="Pending"
                />

            <item
                android:id="@+id/action_status_approved"
                android:title="Approved"
                />

            <item
                android:id="@+id/action_status_rejected"
                android:title="Rejected"
                />
        </menu>
    </item>
</menu>

Use ViewModel and SingleLiveEvent/LiveData to store selected menu status.

class TestListViewModel: ViewModel() {    internal var statusEvent = SingleLiveEvent<Int>()}

Activity

class Approval {    companion object {        const val APPROVED = 1        const val PENDING = 0        const val REJECTED = -1    }}class TestListActivity : AppCompatActivity() {    private lateinit var viewModel: TestListViewModel      override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.testlist)        setSupportActionBar(toolbar)        viewModel = ViewModelProviders.of(this).get(TestListViewModel::class.java)        initUi()    }    override fun onCreateOptionsMenu(menu: Menu): Boolean {        menuInflater.inflate(R.menu.adminquotelist, menu)        val statusMenuItem = menu.findItem(R.id.action_status)        // update menu item title based on selected sub menu item        statusMenuItem.title = when(viewModel.statusEvent.value) {            Approval.APPROVED -> "Approved"            Approval.REJECTED -> "Rejected"            Approval.PENDING -> "Pending"            else -> "Unknown"        }        return super.onCreateOptionsMenu(menu)    }    override fun onOptionsItemSelected(item: MenuItem): Boolean {        // sub menu selection trigger LiveData        return when(item.itemId) {            R.id.action_status_approved -> {                viewModel.statusEvent.value = Approval.APPROVED                true            }            R.id.action_status_pending -> {                viewModel.statusEvent.value = Approval.PENDING                true            }            R.id.action_status_rejected -> {                viewModel.statusEvent.value = Approval.REJECTED                true            }            else -> super.onOptionsItemSelected(item)        }    }    private fun initUi() {        viewModel.statusEvent.observe(this, Observer { status ->            // update menu title with selected sub menu item            invalidateOptionsMenu()            // do something        })        // initialize        viewModel.statusEvent.value = Approval.PENDING    }    }

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.