johannilsson / android-actionbar

DEPRECATED Android Action Bar Implementation
1.3k stars 564 forks source link

Add possibility to inflate actions from menu xml's #7

Open johannilsson opened 13 years ago

Esteth commented 13 years ago

I'd love this, but I'm not sure it's possible?

johannilsson commented 13 years ago

Not sure either, but I hope there's some way to extend the namespace for the standard menu to add at least the class for an action implementation.

LorneLaliberte commented 13 years ago

I'm not sure if it's possible to extend the MenuItem XML to include the class names, etc. but it is definitely possible to dynamically create intents from XML data.

You simply need to provide the class names in array form, and then use that with Class.forName() to get the Class parameter when creating the intent.

The names can either be provided using the full declarations, e.g. packagename.classname, or just as class names that you can prepend the current package name to.

So, for example, you could provide a string array named "activity_classes" and use that to provide the class name for the navigation list intents based on array position. (You could also combine the list item text and the class name in an array and access the items via a different adapter.)

Then simply do something like this, for example in onNavigationItemSelected:

String[] classes = getResources().getStringArray(R.array.activity_classes);
//...
String className = packageName+"."+classes[itemPosition];
Intent intent = new Intent(Main.this, Class.forName(className));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

In the above snippet, packageName could either be specified in the array, replaced by a literal, or calculated earlier in the code like so:

final String packageName = this.getPackageName();

So, it should at least be possible to cross reference menu item ids with a collection of class names (either another array, or a map, or...).

johannilsson commented 13 years ago

Thanks, actually in the next version we're doing action inflation from the menu xml. I guess we'll skip the intent generation and instead rely on the callback as we normally do with menu items.

An example of how this will be done can be found in OtherActivity.java within the example app of that branch.

LorneLaliberte commented 13 years ago

Yep, I'm already using the mimic-native-api branch. Unless I'm missing something, though, that example only shows how to inflate the action items from XML...the intents are still created in "static" Java code, e.g. after switching on the item id in onOptionsItemSelected.

For our project I was interested in making the navigation list intents originate "dynamically" from XML, and it occurred to me that the same approach could be used for inflated action items.

I'm relatively new at Android development so forgive me if I'm stating something obvious. :)

JakeWharton commented 13 years ago

This is beyond the scope of just the action bar because it introduces functionality into the xml file that would only work with this specific implementation. So if you wanted to use the same xml with a normal options or context menu, or in the future you changed the action bar library to another implementation that happened to support xml inflation, you would lose the automatic Intents.

If you want to do this, the best way would be to implement the custom menu inflater yourself. Then you can just use an instance of it rather than calling the activity's getMenuInflater() method. You could then use this custom inflater on any interface that supported Menu/MenuItem and it would always work the same, including options menus and context menus. It would actually be a rather elegant solution.

johannilsson commented 13 years ago

Yes, we don't want to do too much custom stuff here. I had the idea of dynamically create intents before the native action bar was introduced. If Google will release an action bar widget for pre api level 11 I believe they will use the menu approach, as they already do in the IO app. If they do ship such a widget there won't be too much problem migrating away from this implementation if we try to stay as close as possible to the standard approach.

LorneLaliberte commented 13 years ago

@JakeWharton: Thanks for the tip to use a custom inflater, I might give that a shot.

Luckily that level of elegance isn't a requirement for our project :) so if all else fails I'll be able to get by with something simpler, e.g. multiple string arrays.

@johannilsson: good point about future compatibility, too.