Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lesson 7 Using Menus Victor Matos Cleveland State University Portions of this page are reproduced from work created and shared by Google and used according.

Similar presentations


Presentation on theme: "Lesson 7 Using Menus Victor Matos Cleveland State University Portions of this page are reproduced from work created and shared by Google and used according."— Presentation transcript:

1 Lesson 7 Using Menus Victor Matos Cleveland State University Portions of this page are reproduced from work created and shared by Google and used according to termsshared by Google described in the Creative Commons 3.0 Attribution License.Creative Commons 3.0 Attribution License

2 Menus are used to allow Android apps to enhance their functionality. When displayed, a menu is shown as an overlapping layer on top of the current UI. After making a selection, the exposed Menu layer disappear. In principle, a single Menu could add an unlimited number of additional operations (caution - perhaps not a good practice!). An application could have any number of menus. CAUTION Android no longer requires a dedicated Menu button. Developers are advise to migrate away from the notion of a hardware button, as most new devices do not have one (see Example3). Why Menus? Using Menus 7 – 2

3 Android supports two types of menus: Options Menu and Context Menu. 1.The options menu is triggered by pressing the device’s hardware or virtual Menu button. There is only ONE option menu for each UI. 2.A context menu is raised by a tap- and-hold interaction (long-tap) on the widget associated to the menu. You may set one context menu on any widget. Menu Types Using Menus 7 – 3

4 Press the physical Menu button Options available in this context A maximum of six entries per menu. Excess is displayed as part of the More option First Generation G1 Phone. Most modern handsets do not include a hardware MENU button Using Menus (Legacy Style) Figure 1. Using an option menu & physical menu button 7 – 4

5 Figure 2. Hardware Menu Button on the SDK4.3 emulator Press Menu button List of Options available in this context Using Menus 7 – 5

6 Figure 2. Hardware Menu Button on the SDK2.3 emulator Press Menu button List of Options available in this context Using Menus 7 – 6

7 Figure 3. Using an option menu & device’s virtual menu button (Image from an HTC One Phone) Press virtual Menu button Using Menus 7 – 7

8 Figure 4. Dealing with text messages by using the built-in Messaging app’s context menu Messages Context menu options Using Menus 7 – 8

9 Example 1. Attaching a Simple Option and Context Menu 1.In this example an app will show two EditText boxes. Their content will be formatted using services offered by various menus. 2.When the user clicks on the Option-Menu button the app presents options to change point-size, and color of the text held in the EditText boxes. 3.When the user applies a long-tap on the second textbox a menu is shown offering help in changing the text style (Bold, Italic, Underlined) 4.A long-tap on the first textbox displays the same options listed by the option menu. Based on an example from: The Busy Coder's Guide to Android Development by Mark L. Murphy Copyright © 2008-2009 CommonsWare, LLC. ISBN: 978-0-9816780-0-9 7 – 9 Menus - Legacy Style A COMMENT ON ‘LEGACY’ STYLES: A newer (and perhaps better) way of setting OPTION MENUS is discussed in next examples, however; CONTEXT MENUS are still constructed using the strategy described here in Example1.

10 Example 1 Click on Menu button to see size options After choosing option: 50 points This Option Menu offers a way of changing the text size & color of the EditText boxes. Option Menu button Menus - Legacy Style 7 – 10

11 Example 1: Using a Context Menu Long-press a textbox to invoke its Context Menu Each view has its own Context Menu exposing choices appropriate to each one. Menus - Legacy Style 7 – 11

12 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } Example1. Option & Context Menu – Main Layout Menus - Legacy Style 7 – 12 Menu handling code skeletons made by the ADT “Blank Activity” wizard.

13 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/txtBox1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Hello world" /> <EditText android:id="@+id/txtBox2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Hola mundo" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Press the MENU key, or \nLong-press text-boxes" /> Example1. Option & Context Menu – Main Layout Menus - Legacy Style 7 – 13

14 public class MainActivity extends Activity { EditText txtBox1; EditText txtBox2; Integer[] arrayPointSize = {10, 20, 30, 40, 50}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtBox1 = (EditText)findViewById(R.id.txtBox1); txtBox2 = (EditText)findViewById(R.id.txtBox2); // you may register an individual context menu for each view registerForContextMenu(txtBox1); registerForContextMenu(txtBox2); } //onCreate Example1. Option & Context Menu – MainActivity.java 1 Menus - Legacy Style 7 – 14

15 // detect what view is calling and create its context menu @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // decide what context menu needs to be made if (v.getId() == txtBox1.getId()) // create a menu for txtBox1 box populateMyFirstMenu(menu); if (v.getId() == txtBox2.getId()){ // create a menu for txtBox2 box populateMySecondMenu(menu); } } //onCreateContextMenu // set the option menu for the current activity @Override public boolean onCreateOptionsMenu(Menu menu) { // only one Option-Menu per Activity populateMyFirstMenu(menu); return true; } Example1. Option & Context Menu – MainActivity.java 23 Menus - Legacy Style 7 – 15

16 private void populateMyFirstMenu(Menu menu){ int groupId = 0; //arguments: groupId, optionId, order, title menu.add(groupId, 1, 1, "10 points"); menu.add(groupId, 2, 2, "20 points"); menu.add(groupId, 3, 3, "30 points"); menu.add(groupId, 4, 4, "40 points"); menu.add(groupId, 5, 5, "50 points"); menu.add(groupId, 6, 8, "Red text"); menu.add(groupId, 7, 7, "Green Text"); menu.add(groupId, 8, 6, "Blue text"); } //populateMyFirstMenu private void populateMySecondMenu(Menu menu){ int groupId = 0; //arguments: groupId, optionId, order, title menu.add(groupId, 9, 1, "Bold"); menu.add(groupId, 10, 2, "Italic"); menu.add(groupId, 11, 3, "Normal"); }//populateMySecondMenu Example1. Option & Context Menu – MainActivity.java 4 Menus - Legacy Style 7 – 16

17 // called whenever an item in your context menu is selected @Override public boolean onContextItemSelected(MenuItem item) { return applyMenuOption( item ); } // called whenever an item in your options menu is selected @Override public boolean onOptionsItemSelected(MenuItem item) { return applyMenuOption( item ); } Note: boolean event observers of the type onEvent(... ) by convention return : true to indicate the triggered event has been consumed by the method, and false to signal that the event is still alive and could be consumed by others. Example1. Option & Context Menu – MainActivity.java 56 Menus - Legacy Style 7 – 17

18 // apply the action associated to selected item private boolean applyMenuOption(MenuItem item){ int menuItemId = item.getItemId(); //1, 2, 3,...11 String strMsg2 = txtBox2.getText().toString(); if (menuItemId <= 5) { // first five option are for setting text size (10pt, 20pt,... ) int newPointSize = arrayPointSize[menuItemId - 1]; txtBox1.setTextSize(newPointSize); txtBox2.setTextSize(newPointSize); } else { // either change color on txtBox1 or style on txtBox2 if (menuItemId == 6) txtBox1.setTextColor(color.background_dark | Color.RED); // red else if (menuItemId == 7) txtBox1.setTextColor(0xff00ff00); // green else if (menuItemId == 8) txtBox1.setTextColor(0xff0000ff); // blue else if (menuItemId == 9) txtBox2.setText(beautify(strMsg2, "BOLD")); //bold else if (menuItemId == 10) txtBox2.setText(beautify(strMsg2, "ITALIC")); //italic else if (menuItemId == 11) txtBox2.setText(beautify(strMsg2, "NORMAL")); //normal } return false; } //applyMenuOption Example1. Option & Context Menu – MainActivity.java 7 Menus - Legacy Style 7 – 18

19 // changing text style using HTML formatting // Spanned is text to which you could add formatting features private Spanned beautify (String originalText, String selectedStyle){ Spanned answer = null; if (selectedStyle.equals("BOLD")) answer = Html.fromHtml(" " + originalText +" "); else if (selectedStyle.equals("ITALIC")) answer = Html.fromHtml(" " + originalText +" "); else if (selectedStyle.equals("NORMAL")) answer = Html.fromHtml(" " + originalText +"</normal"); return answer; } //beautify } //class Example1. Option & Context Menu – MainActivity.java 8 Menus - Legacy Style 7 – 19

20 1.Indicate which widget(s) on your activity have context menus. To do this, call registerForContextMenu(theWidget) This statement generates a call to the onCreateContextMenu method. 2.Implement onCreateContextMenu(…), populate your menu adding options. This method is called each time the context menu is requested, after it is used it gets discarded Parameters menu The context menu that is being built v The view for which the context menu is being built menuInfo Extra information about the item for which the context menu should be shown. This information will vary depending on the class of v. 3.Implement onCreateOptionMenu(…). You need to populate the activity’s menu by adding its options as shown by Bullet 4. An OptionMenu is created only once for each activity. Example1. Comments 7 – 20 Menus - Legacy Style

21 4.The construction of a menu object requires you to supply each individual choice that will be offered to the user. Choices are added using the statement: menu.add(groupId, optionId, order, title); 5.To find out which context menu choice was made, you need to implement the method onContextItemSelected(). 6.To service requests for the activity’s OptionMenu you need to override the method onOptionsItemSelected(). 7.After the user clicks on a menu item, a reference to this choice is supplied to our service routine applyMenuOption. There we use item.getItemId() to obtain its ID and switch to the appropriate set of service actions. 8.The beautification of simple text is accomplished by applying style HTML tags to the string. For instance simple message returns simple message (Text is rendered bold and in italics) Example1. Comments 7 – 21 Menus - Legacy Style

22 Extending Example1. Keyboard shortcuts / links Example 2: Enhancing Option/Context Menu with SubMenus A Menu Hierarchy This legacy app was designed for an SDK predating Level 14 (no ActionBar on top). An overlapping layer at the bottom of the screen shows up to six choices for a request to bring the activity’s Option Menu. If you have more than six selections the button More will display the remaining entries on a simple list. Menus - Legacy Style Images taken from app targeting SDK 10. 7 – 22

23 Extending Example1. Example 2: Enhancing Option/Context Menu with SubMenus A Menu Hierarchy The previous app is now shown when running on an device set for SDK Level 18. The overlapping layer at the bottom of the screen is replaced by a floating list of options. An option in the list could be a call to another submenu. Observe item on fifth row Sub-Menu-CINCO is one of such kind. Images taken from app targeting SDK 18. Menus - Legacy Style 7 – 23

24 Creating a Hierarchy of Menus. A Sub-Menu item shows a DialogBox displaying the associated sub-options. In this example item-5 is a SubMenu type. Extending Example1. Keyboard shortcuts / links Example 2: Enhancing Option/Context Menu with SubMenus Images taken from app targeting SDK 10. Menus - Legacy Style 7 – 24

25 A Sub-Menu item shows a DialogBox displaying the associated sub- options. Selected sub-menu item known through its.getOrder() method Extending Example1. Keyboard shortcuts / links Example 2: Enhancing Option/Context Menu with SubMenus Images taken from app targeting SDK 10. Menus - Legacy Style 7 – 25

26 Add icons to the app’s folder: res/drawable Do this, only in case you are developing a legacy type app running on a platform earlier than Level-14. Extending Example1. Example 2: Enhancing Option/Context Menu with SubMenus. NOTE A handful of icons are available in the folder: … android-sdk/docs/images/icon-design Menus - Legacy Style For standard Android ActionBar icons see: http://developer.android.com/design/downloads/index.html 7 – 26

27 private void populateMyFirstMenu(Menu menu){ int groupId = 0; //arguments: groupId, optionId, order, title MenuItem item1 = menu.add(groupId, 1, 1, "10 points"); MenuItem item2 = menu.add(groupId, 2, 2, "20 points"); MenuItem item3 = menu.add(groupId, 3, 3, "30 points"); MenuItem item4 = menu.add(groupId, 4, 4, "40 points"); //MenuItem item5 = menu.add(groupId, 5, 5, "50 points"); MenuItem item6 = menu.add(groupId, 6, 8, "Red text"); MenuItem item7 = menu.add(groupId, 7, 7, "Green Text"); MenuItem item8 = menu.add(groupId, 8, 6, "Blue text"); //set icons item1.setIcon(R.drawable.ic_menu_add); item2.setIcon(R.drawable.ic_menu_add); item3.setIcon(R.drawable.ic_menu_archive); item4.setIcon(R.drawable.ic_menu_call); Extending Example1. Icons are added to first four entries of the Option Menu Remove this line from previous version Example 2: MainActivity.java Replace the method populateMyFirstMenu (Example1) with the following code Menus - Legacy Style 7 – 27

28 // adding a sub-menu as fifth entry of this menu //.addSubMenu(int groupId, int itemId, int order, CharSequence title) int smGroupId = 0; // don't care, same as Menu.NONE int smItemId = 5; // fifth element int smOrder = 5; // don't care, same as Menu.NONE SubMenu mySubMenu5 = menu.addSubMenu(smGroupId, smItemId, smOrder, "Sub-Menu-CINCO"); mySubMenu5.setHeaderIcon(R.drawable.btn_rating_star_on_pressed); mySubMenu5.setIcon(R.drawable.ic_menu_compass); //.add(int groupId, int itemId, int order, CharSequence title) MenuItem sub51 = mySubMenu5.add(smGroupId,5,1,"Sub Menu 5-1"); MenuItem sub52 = mySubMenu5.add(smGroupId,5,2,"Sub Menu 5-2"); MenuItem sub53 = mySubMenu5.add(smGroupId,5,3,"Sub Menu 5-3"); } //populateMyFirstMenu Extending Example1. Example 2: MainActivity.java Replace the method populateMyFirstMenu (Example1) with the following code Menus - Legacy Style 7 – 28

29 private boolean applyMenuOption(MenuItem item){ int menuItemId = item.getItemId(); //1, 2, 3,...11 String strMsg2 = txtBox2.getText().toString(); if (menuItemId < 5) { // first four options are for setting text size int newPointSize = arrayPointSize[menuItemId - 1]; txtBox1.setTextSize(newPointSize); txtBox2.setTextSize(newPointSize); } else if (menuItemId == 5) { // the sub-menu (attached to 5th item) is processed here txtBox1.setText ( "You have selected: \n" +item.getTitle() + "\nId: " + menuItemId + " order: " + item.getOrder() ); } // either change color on text1 or style on text2 else if (menuItemId == 6) txtBox1.setTextColor(0xffff0000); // red Extending Example1. Same as before Take care of sub-menu here Example 2: MainActivity.java Replace the method applyMenuOption (Example1) with the following code Menus - Legacy Style 7 – 29

30 else if (menuItemId == 7) txtBox1.setTextColor(0xff00ff00); // green else if (menuItemId == 8) txtBox1.setTextColor(0xff0000ff); // blue else if (menuItemId == 9) txtBox2.setText(beautify(strMsg2, "BOLD")); //bold else if (menuItemId == 10) txtBox2.setText(beautify(strMsg2, "ITALIC")); //italic else if (menuItemId == 11) txtBox2.setText(beautify(strMsg2, "NORMAL")); //normal return false; } //applyMenuOption Extending Example1. Same as in Example1 Example 2: MainActivity.java Replace the method applyMenuOption (Example1) with the following code Menus - Legacy Style 7 – 30

31 Assume you are using Eclipse and running and SDK newer than Level 14. The New > ‘Android Application Project’ wizard allows you to choose a “Blank Activity”. The newly created blank activity provides the skeleton of the onCreate method as well as two menu handling methods: onCreateOptionsMenu onOptionsItemSelected Using Menus – Suggested Practice Example 3: Using the Menu-Snippet Created by Eclipse+ADK 7 – 31

32 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } Example 3. Wizard’s Generated Code Menu handling code skeletons made by the ADT “Blank Activity” wizard. Using Menus – Suggested Practice

33 The call to onCreateOptionsMenu shown in the previous code fragment inflates the above XML menu file stored in /res/menu/activity_main.xml. (the file above has been slightly modified to included a few more items) <item android:id="@+id/menu_settings1" android:orderInCategory="100" android:title="Menu-Option-1"/> <item android:id="@+id/menu_settings2" android:orderInCategory="110" android:title="Menu-Option-2"/> <item android:id="@+id/menu_settings3" android:orderInCategory="120" android:title="Menu-Option-3"/> Example 3: Wizard’s – Menu’s XML Definition Using Menus – Suggested Practice 7 – 33

34 @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); String text = " ID: " + item.getItemId() + " title: " + item.getTitle(); if (id == R.id.menu_settings1) { Toast.makeText(getApplication(), text, Toast.LENGTH_LONG).show(); return true; } if (id == R.id.menu_settings2) { Toast.makeText(getApplication(), text, Toast.LENGTH_LONG).show(); return true; } if (id == R.id.menu_settings3) { Toast.makeText(getApplication(), text, Toast.LENGTH_LONG).show(); return true; } return super.onOptionsItemSelected(item); } Example 3: Using the Menu-Snippet Created by Eclipse+ADK Using Menus – Suggested Practice 7 – 34 This code fragment grabs the selected item and toasts its ID and Title. Observe it returns true to keep the event alive.

35 Our example produces the following snapshots: Example 3: Using the Menu-Snippet Created by Eclipse+ADK ActionBar showing OVERFLOW button Using Menus – Suggested Practice 7 – 35

36 The content and location of the ActionBar (discussed in Lesson 6) can be adjusted to make room not only for its basic Tabs but also portions of the activity’s Option Menu. There are several reasons to follow this practice: 1.Aesthetics 2.More homogeneous look-&-feel 3.Distribution of the Tabs and menu-items from the OptionMenu is done by the OS which finds the “best” way of displaying -as much as possible- all of the requested UI elements (top, bottom, multiple rows, overflow button, scrollable parts, etc). 4.Allowing the OS to place visual parts of the ActionBar results not only in a more pleasant rendering of the GUI but also on less code for the developer. Combining Menus and the ActionBar Using Menus – Suggested Practice 7 – 36

37 The app in this example consists of an encapsulating activity and two fragments. The activity displays an ActionBar that exposes two Tabs: Action1 and Action2. The first Tab (Action1) invokes a ListFragment and the second (Action2) presents a fragment showing the layout of Example1. As in Example 1, the two textboxes included in Action2 define individual ContextMenus that when invoked can change the size, color, and style of the text held in the textviews. The app also adds a global OptionMenu. The choices of the menu include: Search for a particular text in the list, Reset the list, and an About item. The activity’s OptionMenu is treated as an extension of the ActionBar Example 4: Combining Menus and the ActionBar Using Menus – Suggested Practice 7 – 37

38 ActionBar and OptionMenu combined. Image taken from a phone running SDK 18 (Portrait Mode) Example 4: Combining Menus and the ActionBar Using Menus – Suggested Practice ⟵ Status Bar ⟵ Action Bar ⟵ OptionMenu 7 – 38

39 Example 4: Combining Menus and the ActionBar Using Menus – Suggested Practice ⟵ Status Bar ⟵ Action Bar showing Tabs and OptionMenu items ActionBar and OptionMenu combined. Image taken from a phone running SDK 18 (Landscape Mode) 7 – 39

40 Example 4: Combining Menus and the ActionBar Using Menus – Suggested Practice Status Bar Action Bar showing Tabs and OptionMenu items ActionBar and OptionMenu combined. Image taken from a Nexus7 tablet running SDK 18 (Portrait Mode) 7 – 40

41 7 – 41 Example 4: Combining Menus and the ActionBar Using Menus – Suggested Practice

42 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" > Example 4: Layoutactivity_main.xml Using Menus – ActionBar & OptionMenu 7 – 42

43 Example 4: Layoutfragment2_layout.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment2_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/txtBox1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Hello world" /> <EditText android:id="@+id/txtBox2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Hola mundo" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Press the MENU key, or \nLong-press text-boxes" /> 7 – 43 Using Menus – ActionBar & OptionMenu

44 Example 4: Layout search_box.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_action_search" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Search" android:textAppearance="@android:style/TextAppearance.Medium" /> <EditText android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="2dp" android:imeActionId="1111" android:imeOptions="actionDone" android:inputType="text" android:width="100sp" /> Using Menus – ActionBar & OptionMenu 7 – 44

45 Example 4: Menuoption_menu_choices.xml <item android:id="@+id/search" android:actionLayout="@layout/search_box" android:showAsAction="ifRoom|withText" android:title="Search"/> <item android:id="@+id/reset" android:icon="@drawable/ic_action_refresh" android:showAsAction="ifRoom|withText" android:title="Reset"/> <item android:id="@+id/about" android:icon="@drawable/ic_4_collections_view_as_list" android:showAsAction="never" android:title="About"/> Using Menus – ActionBar & OptionMenu 7 – 45

46 Example 4: Menuoption_menu_choices.xml <menu <item... android:showAsAction="ifRoom|withText".../>... Using Menus – ActionBar & OptionMenu 7 – 46 ValueDescription ifRoom Put this item in the Action Bar (if there is room for it). withText Include the title text (defined by android:title) with the action item. never Never place this item in the Action Bar. always Always place this item in the Action Bar. It can result in captions overlapping with other UI in the action bar. collapseActionView The action view associated with this action item (as declared by android:actionLayout or android:actionViewClass) is collapsible.. Reference: http://developer.android.com/guide/topics/resources/menu-resource.html How to show individual Menu Items

47 public class ActionBarMain extends Activity implements OnMyCustomRowSelectedListener, TabListener, OnEditorActionListener { // TAGs identifying ActionBar TABs final String TAG1 = "Action1"; final String TAG2 = "Action2"; // this is the row# picked up in Fragment1(ListView) Integer selectedRow = 0; String searchWord = ""; String lastTag = TAG1; // host layout where fragments are displayed FrameLayout mainLayout; // fragment objects FragmentTransaction fragTransactMgr = null; Fragment currentFragment; // name of control variables saved as state info. private final String SELECTED_ROW = "selectedRow"; private final String SEARCH_WORD = "searchWord"; private final String LAST_TAG = "lastTag"; // reference to SEARCH TextBox TextView referenceToSearchWord; Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 47

48 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mainLayout = (FrameLayout) findViewById(R.id.mainLayout); try { // dealing with device rotation & re-starting // if needed bring back previous state info including // selected row and search word, then destroy the bundle if (savedInstanceState != null) { selectedRow = savedInstanceState.getInt(SELECTED_ROW, 0); searchWord = savedInstanceState.getString(SEARCH_WORD, ""); lastTag = savedInstanceState.getString(LAST_TAG, TAG1); savedInstanceState = null; } // construct & show the ActionBar for this activity fragTransactMgr = getFragmentManager().beginTransaction(); ActionBar bar = getActionBar(); // create fresh tab(s) adding caption and icon bar.addTab(bar.newTab().setText("Action1").setTag(TAG1).setIcon(R.drawable.ic_4_collections_view_as_list).setTabListener(this)); Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 48

49 bar.addTab(bar.newTab().setText("Action2").setTag(TAG2).setIcon(R.drawable.ic_4_collections_view_as_list).setTabListener(this)); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); bar.setDisplayShowHomeEnabled(true); bar.setDisplayShowTitleEnabled(true); bar.show(); // clicking on first TAB ("Action1") bar.selectTab(bar.getTabAt(0)); fragTransactMgr.commit(); } catch (Exception e) { } }// onCreate private void executeFragment(int containerLayoutId, Fragment fragment, String tag) { // our input fragment comes with a bundle already set with arguments // replace the indicated layout with the chosen fragment FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(containerLayoutId, fragment, tag); ft.commit(); } Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 49

50 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // at the end! (phone was rotated or app was terminated) // Save important state info (row, tab, searchWord...) outState.putInt(SELECTED_ROW, selectedRow); outState.putString(SEARCH_WORD, searchWord); outState.putString(LAST_TAG, lastTag); } // --------------------------------------------------------------------------- @Override public boolean onCreateOptionsMenu(Menu menu) { // each activity (regardless of how many Fragments it hosts) // is allowed one OptionMenu. Do the inflation of it here. getMenuInflater().inflate(R.menu.option_menu_choices, menu); configureActionItem(menu); return super.onCreateOptionsMenu(menu); } // ---------------------------------------------------------------------------- private void configureActionItem(Menu menu) { // attach a listener to the search-word textbox EditText searchBox = (EditText) menu.findItem(R.id.search).getActionView().findViewById(R.id.title); searchBox.setOnEditorActionListener(this); } Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 50

51 @Override public boolean onOptionsItemSelected(MenuItem item) { // OPTIONS-MENU. let user know about the selected menu option Toast.makeText(this, "Option selected: " + item.getTitle(), Toast.LENGTH_SHORT).show(); // attending RESET option if (item.getTitle().equals("Reset")) { // RESET. make a new Fragment1 passing an int (selectedRow=0) // this will move the cursor to the top of the list selectedRow = 0; searchWord = ""; if ( referenceToSearchWord != null){ referenceToSearchWord.setText(""); // clear search box } Fragment fragment = addArgsToFragment(new Fragment1(), selectedRow, searchWord, lastTag); executeFragment(R.id.mainLayout, fragment, TAG1); } return true; } Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 51

52 // Accept a fragment, and simple arguments, put those arguments // into a bundle and bind the fragment with the bundle. // This approach is required for apps running SDK Level-14+ public E addArgsToFragment(E fragment, int selectedRow, String searchWord, String lastTag) { // E represents: Fragment1, Fragment2, or Fragment3 classes Bundle bundle = new Bundle(); bundle.putInt(SELECTED_ROW, selectedRow); bundle.putString(SEARCH_WORD, searchWord); bundle.putString(LAST_TAG, lastTag); fragment.setArguments(bundle); return fragment; } // --------------------------------------------------------------------- // this method supports fragment-to-Activity communication. When // a row in Fragment1 is selected, our custom callBack is invoked. // It updates the valued of 'selectedRow' held in the main activity. @Override public void onMyCustomRowSelected(Integer selectedRow) { // as soon as the user picks a row in fragment1, // its value (position in the list) is saved here this.selectedRow = selectedRow; } Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 52

53 @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { // TODO Auto-generated method stub } //--------------------------------------------------------------------- @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { try { Fragment fragment = null; String strTag = (String) tab.getTag(); if (strTag.equals(TAG1)) { // search fragment fragment = addArgsToFragment(new Fragment1(), selectedRow, searchWord, TAG1); } if (strTag.equals(TAG2)) { // reset fragment fragment = addArgsToFragment(new Fragment2(), selectedRow, searchWord, TAG2); } executeFragment(mainLayout.getId(), fragment, strTag ); } catch (Exception e) { Toast.makeText(getApplicationContext(), "MAIN-onTabSelected ERROR:" + tab.getText() + "\n" + e.getMessage(), Toast.LENGTH_SHORT).show(); } Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 53

54 @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { // TODO Auto-generated method stub } @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if ((event == null) || (event.getAction() == KeyEvent.ACTION_UP)) { // obtain a reference to searchBox, get its text, initiate search referenceToSearchWord = v; searchWord = v.getText().toString(); Toast.makeText(getApplicationContext(), "Searching for: " + searchWord, Toast.LENGTH_SHORT).show(); // remove keyboard from search box InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); // make a new Fragment1 passing a search string, let the new fragment locate // the searchWord entered in the OptionMenu box. Fragment fragment = addArgsToFragment(new Fragment1(), selectedRow, searchWord, lastTag); executeFragment(R.id.mainLayout, fragment, TAG1); } return true; } }// class Example 4: Main Activity – ActionBarMain.java Using Menus – ActionBar & OptionMenu 7 – 54

55 Example 4: Fragment1.java – Showing a ListView Using Menus – ActionBar & OptionMenu 7 – 55

56 // this fragment shows a ListView from which a row will be selected public class Fragment1 extends Fragment { OnMyCustomRowSelectedListener mListener; int selectedRow = 0; String searchWord = ""; private String items[] = { "Text-on-Line-01", "Text-on-Line-02", "Text-on-Line-03", "Text-on-Line-04", "Text-on-Line-05", "Text-on-Line-06", "Text-on-Line-07", "Text-on-Line-08", "Text-on-Line-09", "Text-on-Line-10", "Text-on-Line-11", "Text-on-Line-12", "Text-on-Line-13", "Text-on-Line-14", "Text-on-Line-15"}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // instead of an XML spec, this view is created with code Context context = getActivity(); ListView listView = new ListView(context); Example 4: Fragment1.java – Showing a ListView Using Menus – ActionBar & OptionMenu 7 – 56

57 ArrayAdapter adapter = new ArrayAdapter (context, android.R.layout.simple_list_item_1, items); listView.setAdapter(adapter); selectedRow = getArguments().getInt("selectedRow", 0); searchWord = getArguments().getString("searchWord",""); if (searchWord.length()>0){ selectedRow = findWordInList(searchWord, listView); } listView.setSelection(selectedRow); listView.smoothScrollToPosition(selectedRow); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View v, int position, long id) { Toast.makeText(getActivity(), "FRAG1. You picked: " + position, 1).show(); // Send the event and clicked item's row ID to the host activity mListener.onMyCustomRowSelected(position); } }); return listView; }// onCreateView Example 4: Fragment1.java – Showing a ListView Using Menus – ActionBar & OptionMenu 7 – 57

58 private int findWordInList(String searchWord, ListView listView) { for(int i=0; i<listView.getCount(); i++){ String currentRow = (String) listView.getItemAtPosition(i); if (currentRow.contains(searchWord)){ Toast.makeText(getActivity(), "FRAG. " + searchWord + " FOUND "+ i, 1).show(); mListener.onMyCustomRowSelected(i); return i; } Toast.makeText(getActivity(), "FRAG. " + searchWord + " NOT FOUND", 1).show(); mListener.onMyCustomRowSelected(0); return 0; } //--------------------------------------------------------------------- // making sure the MainActivity has implemented the listener // and can accept our callback messaging @Override public void onAttach(Activity activity) { super.onAttach(activity); // Activities containing this fragment must implement its callbacks. if (!(activity instanceof OnMyCustomRowSelectedListener)) { throw new IllegalStateException( "Activity must implement OnMyCustomPictureSelectedListener."); } mListener = (OnMyCustomRowSelectedListener) activity; }// onAttach }// class Example 4: Fragment1.java – Showing a ListView Using Menus – ActionBar & OptionMenu 7 – 58

59 Example 4: Fragment2.java – Defining a ContextMenu Using Menus – ActionBar & OptionMenu 7 – 59

60 Example 4: Fragment2.java – Defining a ContextMenu Using Menus – ActionBar & OptionMenu 7 – 60

61 public class Fragment2 extends Fragment { EditText txtBox1; EditText txtBox2; Integer[] arrayPointSize = { 10, 20, 30, 40, 50 }; LinearLayout fragment2Layout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }// onCreate // --------------------------------------------------------------------- @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment2_layout, null); fragment2Layout = (LinearLayout) view.findViewById(R.id.fragment2_layout); txtBox1 = (EditText) view.findViewById(R.id.txtBox1); txtBox2 = (EditText) view.findViewById(R.id.txtBox2); // you may register an individual context menu for each view registerForContextMenu(txtBox1); registerForContextMenu(txtBox2); return view; }// onCreateView Example 4: Fragment2.java – Defining a ContextMenu Using Menus – ActionBar & OptionMenu 7 – 61

62 // detect what view is calling and re-create its context menu @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // decide what context menu needs to be made if (v.getId() == txtBox1.getId()) // create a menu for txtBox1 box makeMyFirstContextMenu(menu); if (v.getId() == txtBox2.getId()){ // create a menu for txtBox2 box makeMySecondContextMenu(menu); } } //onCreateContextMenu // --------------------------------------------------------------------- private void makeMyFirstContextMenu(Menu menu){ int groupId = 0; //arguments: groupId, optionId, order, title menu.add(groupId, 1, 1, "10 points"); menu.add(groupId, 2, 2, "20 points"); menu.add(groupId, 3, 3, "30 points"); menu.add(groupId, 4, 4, "40 points"); menu.add(groupId, 5, 5, "50 points"); menu.add(groupId, 6, 8, "Red text"); menu.add(groupId, 7, 7, "Green Text"); menu.add(groupId, 8, 6, "Blue text"); } //makeMyFirstContextMenu Example 4: Fragment2.java – Defining a ContextMenu Using Menus – ActionBar & OptionMenu 7 – 62

63 private void makeMySecondContextMenu(Menu menu){ int groupId = 0; //arguments: groupId, optionId, order, title menu.add(groupId, 9, 1, "Bold"); menu.add(groupId, 10, 2, "Italic"); menu.add(groupId, 11, 3, "Normal"); }//makeMySecondContextMenu // --------------------------------------------------------------------- // called whenever an item in your context menu is selected @Override public boolean onContextItemSelected(MenuItem item) { //return(applyMenuOption(item)); int menuItemId = item.getItemId(); //1, 2, 3,...11 String strMsg2 = txtBox2.getText().toString(); if (menuItemId <= 5) { // first five option are for setting text size int newPointSize = arrayPointSize[menuItemId - 1]; txtBox1.setTextSize(newPointSize); txtBox2.setTextSize(newPointSize); } else { // either change color on text1 or style on text2 if (menuItemId == 6) txtBox1.setTextColor(color.background_dark | Color.RED); // red else if (menuItemId == 7) txtBox1.setTextColor(0xff00ff00); // green Example 4: Fragment2.java – Defining a ContextMenu Using Menus – ActionBar & OptionMenu 7 – 63

64 else if (menuItemId == 8) txtBox1.setTextColor(0xff0000ff); // blue else if (menuItemId == 9) txtBox2.setText(beautify(strMsg2, "BOLD")); //bold else if (menuItemId == 10) txtBox2.setText(beautify(strMsg2, "ITALIC")); //italic else if (menuItemId == 11) txtBox2.setText(beautify(strMsg2, "NORMAL")); //normal } return false; } // --------------------------------------------------------------------- // changing text style using HTML formatting // Spanned is text to which you could add formatting features private Spanned beautify (String originalText, String selectedStyle){ Spanned answer = null; if (selectedStyle.equals("BOLD")) answer = Html.fromHtml(" " + originalText +"</b"); else if (selectedStyle.equals("ITALIC")) answer = Html.fromHtml(" " + originalText +" "); else if (selectedStyle.equals("NORMAL")) answer = Html.fromHtml(" " + originalText +"</normal"); return answer; } //beautify }// class Example 4: Fragment2.java – Defining a ContextMenu Using Menus – ActionBar & OptionMenu 7 – 64

65 Example 4: OnMyCustomRowSelectedListener.java Defining a Custom Listener Using Menus – ActionBar & OptionMenu // Note: The MainActivity must implement this interface !!! // Used to tell the MainActivity what row from ListView the user // has selected when interacting with Fragment1 (this is // functionally equivalent to an onClickLister) public interface OnMyCustomRowSelectedListener { public void onMyCustomRowSelected(Integer selectedRow); } 7 – 65

66 Using Menus Questions? Recommended Additional Reading: http://developer.android.com/design/style/iconography.html http://developer.android.com/design/downloads/index.html http://developer.android.com/guide/topics/ui/themes.html http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html


Download ppt "Lesson 7 Using Menus Victor Matos Cleveland State University Portions of this page are reproduced from work created and shared by Google and used according."

Similar presentations


Ads by Google