Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-using Options menu code

Is there a convenient way of showing the same Options menu options in multiple Activities?

Example: In my app, I display a TV Guide in one of three ways.

  1. Seven day guide (TabActivity with 7 tabs)
  2. All channels 'Now showing' (ListActivity)
  3. All shows today by start time (Activity - could be changed easily to ListActivity)

For the Options menu in the TabActivity, the code is quite simple...

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    menu.clear();
    inflater.inflate(R.menu.gv_options_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.view:
        ...
    ...
    }
}

...but at the moment it seems I need to copy/paste it to the other two Activities which I don't like doing. If I change the Options menu code for one I'll need to do it for the other two also.

The only alternative I can think of is I have a 'helper' class (POJO) to which I could add a method and pass the context into to allow use of the getMenuInflator() method and another method I could pass the result of item.getItemId() into to process with the switch-case.

What is the normal way of having multiple Activities with the same Options menu?

like image 583
Squonk Avatar asked Nov 14 '11 02:11

Squonk


2 Answers

Create a simple separate class with these two methods:

public class MyMenuHandler {

    private Activity mActivity;

    public MyMenuHandler(Activity activity) {
        mActivity = activity;
    }

    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuInflater inflater = mActivity.getMenuInflater();
        menu.clear();
        inflater.inflate(R.menu.gv_options_menu, menu);
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.view:
            ...
        }
    }
}

In your activities override those callback methods and redirect the call to an instance of your MyMenuHandler class:

public class MyActivity1 extends TabActivity {

    private MyMenuHandler mMenuHandler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        mMenuHandler = new MyMenuHandler(this);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // you may also add here some items which are specific 
        // for one activity, not for the others
        ...
        return mMenuHandler.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // handle selection of your specific items here,
        // if none of them has been selected call mMenuHandler method
        ...
        return mMenuHandler.onOptionsItemSelected(item);
    }
}

This will let you hold in one place the code which respond to selection of your basic menu items, so there will be no need to worry about copy-pasting it to all activities which are to have the same menu.

like image 121
a.ch. Avatar answered Sep 21 '22 12:09

a.ch.


One approach is to use inheritance with your Activities. Create a base Activity that implements the options menu methods and then each child Activity will gain that functionality. This is the recommended approach on the Android developer site:

Tip: If your application contains multiple activities and some of them provide the same Options Menu, consider creating an activity that implements nothing except the onCreateOptionsMenu() and onOptionsItemSelected() methods. Then extend this class for each activity that should share the same Options Menu. This way, you have to manage only one set of code for handling menu actions and each descendant class inherits the menu behaviors.

Unfortunately this won't work for you as you are not inheriting from Activity itself but differing subclasses of it, but that is the 'normal' way to do it.

like image 20
skynet Avatar answered Sep 22 '22 12:09

skynet