390 likes | 585 Views
Cosc 5/4730. Android: Menus and ActionBar. Android menus, a note. Menus are both very simple and easy to implement And stupidly complex as well. “That seems to be a trend” --N.F. Depending on the API of the device the menu will display in different places
E N D
Cosc 5/4730 Android: Menus and ActionBar
Android menus, a note • Menus are both very simple and easy to implement • And stupidly complex as well. • “That seems to be a trend” --N.F. • Depending on the API of the device the menu will display in different places • It all depends on what you want to do. • And what API version too.
Android menus, a note(2) • From HoneyComb (API 11) and on there is also an actionbar (which can also do things like a menu) • The menu can always be called for with the menu button and no visual clue will be given there is a menu. • On devices without a menu button (say the Nexus7) is will show up in the actionbar • Normally on the far right, as three dots.
Android menus, a note(3) • The all the code in this lecture will be in the menuDemo project. • It will have more then a few activities (and a few fragments) to attempt to demonstrate many of the menu and actionbar features. • A note, the project may force close (with devices below API 11) on some activities, since I’m ignore the API restrictions. • Attempts have been made to prevent it, but it may not always work.
Menu • By default, every Activity supports an options menu of actions or options. You can add items to this menu and handle clicks on your additions • The easiest way to add menu items is override onCreateOptionsMenu(Menu menu) and onOptionsItemSelected(MenuItem) • This works from API 1 on.
onCreateOptionsMenu • create IDs for the menu items, need them later to find out which menu was selected. protected static final intMenu1_ID = Menu.FIRST; protected static final intMenu2_ID = Menu.FIRST+1; • Override and add the menu items you want. @Override public booleanonCreateOptionsMenu(Menu menu) { • add(intgroupId, intitemId, int order, CharSequence) menu.add(0, Menu1_ID, 0, "Menu 1"); menu.add(0, Menu2_ID, 0, "Menu 2"); return super.onCreateOptionsMenu(menu); }
onCreateOptionsMenu (2) • You can also add sub menu as well • addSubMenu • performShortcut(intkeyCode, KeyEvent event, int flags) • Execute the menu item action associated with the given shortcut character. • removeGroup(intgroupId) • Remove all items in the given group. • removeItem(intid) • Remove the item with the given identifier. • clear() • Remove all existing items from the menu, leaving it empty as if it had just been created.
onOptionsItemSelected @Override public booleanonOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case Menu1_ID: //do something return true; //we processed the menu item case Menu2_ID: //do something return true; default: //super does something. return super.onOptionsItemSelected(item); } } This is demonstrated in the mainActivity of the menuDemo and should work on any API.
Menu Example • You can add 5 menu items and the they will stack. With 6 or more menu items, you will get a MORE menu item • So put the important menu items as the first ones and the least important (used) farther down. This menu display for deivces before Honeycomb
JellyBean and menus • Starting in ICS (v3), you can use a xml layout • Also create context or popup menus • A note they are differences between v3 and v4. I’m ignoring v3 and using v4. • First create a menu xml (normally in res/menu) with menu as the type. • You can add items (and sub menus). You can also group the items as well.
Xml example: <group android:id="@+id/group1"> <item android:id="@+id/item1" android:orderInCategory="5" android:title="item1"/> <item android:id="@+id/item2" android:orderInCategory="10" android:title="item2"/> <item android:id="@+id/item3" android:orderInCategory="1" android:title="item3"/> <item android:id="@+id/item4" android:orderInCategory="3" android:title="item4"/> <item android:id="@+id/item5" android:orderInCategory="2" android:title="item5"/> </group> • Note the orderInCategory determines the order of display, so this will show: Item3 Item5 Item3 Item1 item2
Sub menus in xml • Create and item that will be the submenu heading • Then create a menu instead of the item tags. <menu> <item> ... <menu> ... </menu> ... </item> </menu>
Java code • This is all that is needed for onCreateOpensMenu • No constants are needed either. @Override public booleanonCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menuv4, menu); return true; }
onOptionsItemSelected • Use the R.id.X instead of constants. switch (item.getItemId()) { case R.id.item1: //do something return true; …
Popup menus. • Add a click listener (or longtouch, whatever) to anything. • We are using a TextView, so make sure it clickable • It will then call our code, called showPopupMenu(View v) • Note this is not an override, just a method we are using public void onClick(View v) { showPopupMenu(v); }
showPopupMenu private void showPopupMenu(View v){ PopupMenupopupM = new PopupMenu(this, v); popupM.inflate(R.menu.popup); popupM.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public booleanonMenuItemClick(MenuItem item) { //do something return true; } }); popupM.show(); }
Example • Using the menu • Using the popup menu
Fragments and Menus • Fragments can contribute to the menu as well • Including if there is no menu. • In the OnCreate() method of the fragment, you must add • setHasOptionsMenu(true); • Otherwise the menu methods will not be called. • A note, when the fragment is showing, the menu will be there and when the fragment is “removed”, then those menu items are removed as well. • Remember, fragments are nice, because of the encapsulation.
Fragments and Menus (2) • Override the following, note the onCreateOptionsMenu is a little different @Override public void onCreateOptionsMenu(Menu menu, MenuInflaterinflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.frag2menu, menu); } @Override public booleanonOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.frag2item: //do something. return true; } return super.onOptionsItemSelected(item); }
Fragment Example • The show Fragment X is menu from the activity.
Menu creation • Menu items can be changed later by • invalidateOptionsMenu(); • Which calls the onCreateOptionsMenu method again. • So if you need to change, enable/disable menu items, you can pretty easily.
Action Bar • We saw fragments Demo that the Action bar can provide a “Back” button to the parent Activity. • We can also add “buttons”, except they are menu items, via the xml • We can also add sub menu to the ActionBar that drop down when clicked.
Xml code • From Googles page: http://developer.android.com/guide/topics/resources/menu-resource.html • android:showAsAction= • ifRoom • Only place this item in the Action Bar if there is room for it. • withText • Also include the title text (defined by android:title) with the action item. You can include this value along with one of the others as a flag set, by separating them with a pipe |. • never • Never place this item in the Action Bar. • always • Always place this item in the Action Bar. Avoid using this unless it's critical that the item always appear in the action bar. Setting multiple items to always appear as action items can result in them overlapping with other UI in the action bar. • collapseActionView • The action view associated with this action item (as declared by android:actionLayoutor android:actionViewClass) is collapsible. • Introduced in API Level 14.
Xml code example <menu > <item android:id="@+id/actionmenu_settings" android:showAsAction="ifRoom" android:title="@string/action_settings"/> <item android:id="@+id/submenu" android:title="sub menu" android:showAsAction="always"> <menu> <item android:id="@+id/asubitem1" android:orderInCategory="1" android:title="subitem1"/> <item android:id="@+id/asubitem2" android:orderInCategory="2" android:title="subitem2"/> </menu> </item> <item android:id="@+id/amenuitem1" android:title="item1"/> <item android:id="@+id/amenuitem2" android:title="item2"/> </menu> Show if room, if not show in normal menu Always shows and creates a Drop menu (separate from standard Menu) Normal menu items
End result • This shows how it can look • The sub menu item has been clicked to show the sub menu.
Action Bar • We can also have “buttons” as well and change them as needed, programmatically. • This example uses the ViewPager fragment example and adds buttons for Previous and Next • also finish, but that doesn’t do anything • The buttons may show at the bottom of the screen if there is not enough space on the actionbar.
Java code • We need to use the invalidateOptionsMenu(); every time the page is changed, so • Using the ViewPager.setOnPageChangeListener(…) • Otherwise the main work is in the onCreateOptionsMenu(Menu menu)
OnCreateOptionsMenu public booleanonCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.activity_screen_slide, menu); • Enable the previous menu item, if we are not on the first page (xml). • menu.findItem(R.id.action_previous).setEnabled(viewPager.getCurrentItem() > 0); • Add either a "next" or "finish" button to the action bar, depending on which page is currently selected. Done programmatically. MenuItem item = menu.add(Menu.NONE, R.id.action_next, Menu.NONE, (viewPager.getCurrentItem() == mPagerAdapter.getCount() - 1) ? R.string.action_finish : R.string.action_next); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM| MenuItem.SHOW_AS_ACTION_WITH_TEXT); return true; }
And the result looks like • First page: • Third page • Last page
Other things xml . • android:titleCondensed="string“ • android:icon="@[package:]drawable/drawable_resource_name“ • android:onClick="method name“ • android:actionLayout="@[package:]layout/layout_resource_name" • android:actionViewClass="class name" • android:actionProviderClass="class name" • android:alphabeticShortcut="string" • android:numericShortcut="string" • android:checkable=["true" | "false"] • The layout allows you to add say a search bar to the top.
Support-v7-appcompat library • To use the actionbar back to api 7 (v2.1) android has provided a compat library. • Unlike the v4.support it’s not a jar, but project that you use a library. It must be opened in eclipse as well. • Import the project into your workspace • %androidinstall%\android-sdk\extra\android\support\v7\appcompat • Make sure it’s a library • Properties->android Is library checked.
Eclipse and new project • Eclipse may create the directory for you with appcompat (something 2, 3, 4 depends on how many new projects). • Extends ActionBarActivity • Instead of FragmentActivity or Activity • Now all devices will see the ActionBar. • A good reference to convert an older project • http://android-developers.blogspot.com/2013/08/actionbarcompat-and-io-2013-app-source.html
Differences. • menuDemo and menuDemoV7 • No more suppression for API. Everything now works on 2.3.3 • Use import android.support.v7.widget.PopupMenu • Instead of import android.widget.PopupMenu; • Use getSupportActionBar().setDisplayHomeAsUpEnabled(true) • Instead of getActionBar().setDisplayHomeAsUpEnabled(true); • Use supportInvalidateOptionsMenu(); • Instead of invalidateOptionsMenu(); • Use MenuItemCompat.setShowAsAction( item,MenuItem.SHOW_AS_ACTION_IF_ROOM| MenuItem.SHOW_AS_ACTION_WITH_TEXT); • instead of item.setShowAsAction( MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
Differences (2) • Menu xml needs to be changed. • Orginal looks like this: <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_previous" android:title="@string/action_previous" android:showAsAction="ifRoom|withText" /> </menu> • Changes in Red. <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_previous" android:title="@string/action_previous“ app:showAsAction="ifRoom" /> </menu> This attribute is ignored in 2.3.3
Last example. • I’ve included a very nice example, which is not mine. • The Styling Android website provides some nice examples • I’m including the their example of ActionBar since it cover more then I have time for. • Http://blog.stylingandroid.com/archives/2020 • In the git menu directory called ActionBarCompat
References • Surprisingly, very few and mostly google. • http://developer.android.com/guide/topics/resources/menu-resource.html • http://developer.android.com/reference/android/app/Fragment.html#onOptionsItemSelected%28android.view.MenuItem%29 • http://developer.android.com/guide/topics/ui/actionbar.html
Q A &