Using Toolbar as the Action Bar

There is also an option for us to take the Toolbar from our layout and tell AppCompatActivity to use it as the action bar. This has value in some cases, such as when we start working with fragments in an upcoming chapter.

The ActionBar modules in the Sampler and SamplerJ projects are almost the same as the Toolbar modules. We use the same layout, the same menu resource, and the same theme. The difference lies in the Java/Kotlin code for setting up the Toolbar and responding to events.

Registering the Toolbar

To indicate that a Toolbar should serve in the role of the action bar, call setSupportActionBar() on your AppCompatActivity, supplying the Toolbar:

    setSupportActionBar(binding.toolbar);
    setSupportActionBar(binding.toolbar)

The action bar automatically gets the title from its activity’s android:label manifest attribute, so you may not need to call setTitle() yourself on the Toolbar.

Populating the Action Bar

Rather than call inflateMenu() on the Toolbar, the action bar reuses the old onCreateOptionsMenu() callback function from the days of options menus. Your AppCompatActivity subclass — such as MainActivity in the ActionBar samples — will need to override this:

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.actions, menu);

    return super.onCreateOptionsMenu(menu);
  }
  override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.actions, menu)

    return super.onCreateOptionsMenu(menu)
  }

In onCreateOptionsMenu(), you:

Responding to Events

Similarly, instead of calling setOnMenuItemClickListener() on the Toolbar to find out when the user clicks on items, you override the legacy onOptionsItemSelected() function:

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.refresh) {
      vm.refresh();
      adapter.submitList(vm.numbers);
      return true;
    }
    else if (item.getItemId() == R.id.about) {
      Toast.makeText(MainActivity.this, R.string.msg_toast,
        Toast.LENGTH_LONG).show();
      return true;
    }
    else {
      return super.onOptionsItemSelected(item);
    }
  }
  override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when(item.itemId) {
       R.id.refresh -> {
        vm.refresh()
        colorAdapter.submitList(vm.numbers)
        true
      }
      R.id.about -> {
        Toast.makeText(
          this@MainActivity,
          R.string.msg_toast,
          Toast.LENGTH_LONG
        ).show()
        true
      }
      else -> super.onOptionsItemSelected(item)
    }
  }

This function does the same basic thing as the lambda expression supplied to setOnMenuItemClickListener():

In the unrecognized-item scenario, since we chained to the superclass in onCreateOptionsMenu(), we chain to the superclass in onOptionsItemsSelected(). That way, if our superclass is contributing items to the action bar, we will both add those items (onCreateOptionsMenu()) and handle their click events (onOptionsItemSelected()).

Visually, this sample is indistinguishable from the Toolbar one, other than using a different app_name string resource. Functionally, it is merely a matter of where and how you apply the menu resource and deal with the results.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.