Now I'll show how to create options menu that will look like iPhone's Action Sheet.
Preparings.
First let's create animations for the menu. The menu will show from the bottom of the device screen. So the "in" animation will look like:
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%" android:toXDelta="100%" android:fromYDelta="0%" android:toYDelta="100%" android:duration="@android:integer/config_shortAnimTime" android:interpolator="@android:anim/linear_interpolator" > </translate> </set>As you can see it's the "translate" animation. The animated view will be always 100% screen width and will grow from 0% to 100% it's height.
Vice versa the "out" we'll define as following:
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%" android:toXDelta="100%" android:fromYDelta="100%" android:toYDelta="0%" android:duration="@android:integer/config_shortAnimTime" android:interpolator="@android:anim/linear_interpolator" > </translate> </set>
It will shrink from 100% to 0% height.
And to apply the animation to a view:
<style name="Animations.MenuAnimation"> <item name="android:windowEnterAnimation"> @anim/menu_animation_in</item> <item name="android:windowExitAnimation"> @anim/menu_animation_out</item> </style>
The menu items will be the same as in Dialog demo, but with gray colors. And at last to complete XML stuff there are the menu item layout and the menu layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="#224c4c4c" android:gravity="center" android:orientation="vertical" android:padding="4dip" > <Button android:id="@+id/custom_menu_item_caption" style="@style/button_black" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Add from URL" > </Button> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00000000" android:orientation="vertical" android:padding="0dip" > <View android:layout_width="fill_parent" android:layout_height="0.5dip" android:background="#ff4f4f4f" /> <ImageView android:layout_width="fill_parent" android:layout_height="20dip" android:gravity="center" android:scaleType="fitXY" android:src="@drawable/menu_header" /> <View android:layout_width="fill_parent" android:layout_height="0.5dip" android:background="#ff4f4f4f" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#aa000000" android:orientation="vertical" android:padding="0dip" > <TableLayout android:id="@+id/custom_menu_table" android:layout_width="fill_parent" android:layout_height="wrap_content" android:focusable="true" android:focusableInTouchMode="true" android:stretchColumns="*" > </TableLayout> </LinearLayout> </LinearLayout>
Menu Header:
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:angle="270" android:type="linear" android:endColor="#444c4c4c" android:startColor="#44ffffff" /> </shape>
The code
The code is quite clear. On base of the PopupWindow we form our menu. The layout for the popup window is the table layout. And each item of the menu we add to the layout. And to complete the menu we add a listener to each item.
/** * Opened menu */ private static volatile CustomMenu mMenu = null; private ArrayList<CustomMenuItem> mMenuItems; private OnMenuItemSelectedListener mListener = null; private Activity mContext = null; private static volatile PopupWindow mPopupWindow = null; private static boolean mIsShowing = false; /** * Menu item selected listener */ public interface OnMenuItemSelectedListener { public void MenuItemSelectedEvent(Integer selection); } /** * Is the menu opened * * @return boolean isShowing */ public static boolean isShowing() { return mIsShowing; } /** * Constructor * * @param activity * Activity where the menu will be shown * @param OnMenuItemSelectedListener * listener Listener * @param LayoutInflater * items Items list * @return void */ public CustomMenu(Activity activity, OnMenuItemSelectedListener listener, HashMap<Integer, String> items) { mListener = listener; mMenuItems = new ArrayList<CustomMenuItem>(); mContext = activity; // Add items to the menu for (Integer id : items.keySet()) { String name = items.get(id); CustomMenuItem cmi = new CustomMenuItem(); cmi.setCaption(name); cmi.setId(id); mMenuItems.add(cmi); } } public void show(View v) { // The menu is shown mIsShowing = true; int itemCount = mMenuItems.size(); if (itemCount < 1) return; // Nothing to show if (mPopupWindow != null) return; // The menu is opened // Display settings Display display = ((WindowManager) mContext .getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); // The view to show View mView = ((Activity) mContext).getLayoutInflater().inflate( R.layout.custom_menu, null); // Create popup window to show mPopupWindow = new PopupWindow(mView, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, false); mPopupWindow.setAnimationStyle(R.style.Animations_MenuAnimation); mPopupWindow.setWidth(display.getWidth()); mPopupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0); // Add menu items TableLayout table = (TableLayout) mView .findViewById(R.id.custom_menu_table); table.removeAllViews(); for (int i = 0; i < itemCount; i++) { TableRow row = null; Button btn = null; // create headers row = new TableRow(mContext); row.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); final CustomMenuItem cmi = mMenuItems.get(i); View itemLayout = ((Activity) mContext).getLayoutInflater() .inflate(R.layout.custom_menu_item, null); btn = (Button) itemLayout .findViewById(R.id.custom_menu_item_caption); btn.setText(cmi.getCaption()); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mListener.MenuItemSelectedEvent(cmi.getId()); hide(); } }); row.addView(itemLayout); table.addView(row); } }
And we have: