All Projects → ShamylZakariya → Flyoutmenus

ShamylZakariya / Flyoutmenus

Licence: mit
Simple material-style flyout menus for Android. There are many flyout type menus for Android, but this one is mine.

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Flyoutmenus

FancyMenu
Source code for the FancyMenu mod.
Stars: ✭ 93 (-90.65%)
Mutual labels:  menus
react-portal-hoc
A stupid HOC to make a stupid portal so you can make stupid modals
Stars: ✭ 14 (-98.59%)
Mutual labels:  menus
Wp Bootstrap Navwalker
A custom WordPress nav walker class to fully implement the Twitter Bootstrap 4.0+ navigation style (v3-branch available for Bootstrap 3) in a custom theme using the WordPress built in menu manager.
Stars: ✭ 3,290 (+230.65%)
Mutual labels:  menus
gonsole
Integrated console application library, using Go structs as commands, with menus, completions, hints, history, Vim mode, $EDITOR usage, and more ...
Stars: ✭ 18 (-98.19%)
Mutual labels:  menus
cylon-deb
TUI menu driven bash shell script to update and maintain a Debian based Linux distro.
Stars: ✭ 23 (-97.69%)
Mutual labels:  menus
Laravel Nestedset
Effective tree structures in Laravel 4-5
Stars: ✭ 3,045 (+206.03%)
Mutual labels:  menus
react-push-menu
react multi level push menu
Stars: ✭ 37 (-96.28%)
Mutual labels:  menus
Menu
Html menu generator
Stars: ✭ 539 (-45.83%)
Mutual labels:  menus
Qprompt
Python library for quick CLI user prompts, input, and menus.
Stars: ✭ 46 (-95.38%)
Mutual labels:  menus
Wagtailmenus
An app to help you manage and render menus in your Wagtail projects more effectively
Stars: ✭ 275 (-72.36%)
Mutual labels:  menus
PHP-Quick-Menu
This is a PHP Multilevel Menu class. From nested Json|Array to Html menu (ul)
Stars: ✭ 25 (-97.49%)
Mutual labels:  menus
dpymenus
Simplified menus for discord.py developers.
Stars: ✭ 28 (-97.19%)
Mutual labels:  menus
Yoshi
A convenient wrapper around the UI code that is often needed for displaying debug menus.
Stars: ✭ 263 (-73.57%)
Mutual labels:  menus
vue-bottom-navigation
Vue bottom navigation
Stars: ✭ 56 (-94.37%)
Mutual labels:  menus
React Pro Sidebar
Customizable and responsive react sidebar library with dropdown menus and unlimited number of nested submenus
Stars: ✭ 359 (-63.92%)
Mutual labels:  menus
ContextMenuSwift
A better version of iOS 13 Context Menu
Stars: ✭ 162 (-83.72%)
Mutual labels:  menus
ml-stack-nav
Customizable, responsive, accessible, easy-to-use multi-level stack navigation menu with slide effect.
Stars: ✭ 20 (-97.99%)
Mutual labels:  menus
Sidemenu
Simple side/slide menu control for iOS, no code necessary! Lots of customization. Add it to your project in 5 minutes or less.
Stars: ✭ 5,267 (+429.35%)
Mutual labels:  menus
Gallium
Build desktop applications in Go and HTML.
Stars: ✭ 3,694 (+271.26%)
Mutual labels:  menus
M5ez
Complete interface builder for the M5Stack, an ESP32 based mini tinker-computer
Stars: ✭ 260 (-73.87%)
Mutual labels:  menus

FlyoutMenus

Simple material-style flyout menus for Android. There are many flyout type menus for Android, but this one is mine.

compile 'org.zakariya.flyoutmenus:flyoutmenu:0.5.3'
  • minSdkVersion: 14 Note: when running on SDK less than 18, hardware rendering is disabled. This means that button shadows are clipped. To work around this, add a bit of padding to the view.

BasicDemo


XML

<org.zakariya.flyoutmenu.FlyoutMenuView
	android:id="@+id/myMenu"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_marginBottom="@dimen/flyout_menu_button_margin"
	android:layout_marginLeft="@dimen/flyout_menu_button_margin"
	android:layout_marginRight="@dimen/flyout_menu_button_margin"
	android:layout_marginTop="@dimen/flyout_menu_button_margin"
	app:fmButtonSize="@dimen/flyout_menu_button_size"
	app:fmItemHeight="@dimen/palette_menu_item_size"
	app:fmItemMargin="0dp"
	app:fmItemWidth="@dimen/palette_menu_item_size"
	app:fmMenuAnchor="top"
	/>

FlyoutMenuView attributes (all have fm prefix) are:

// the size of the button
<attr name="fmButtonSize" format="dimension"/>

// the background color of the trigger button
<attr name="fmButtonBackgroundColor" format="color"/>

// the background color of the menu
<attr name="fmMenuBackgroundColor" format="color"/>

// the color drawn behind the selected menu item
<attr name="fmSelectedItemBackgroundColor" format="color"/>

// width of items in the menu
<attr name="fmItemWidth" format="dimension"/>

// height of items in the menu
<attr name="fmItemHeight" format="dimension"/>

// margin around items in the menu
<attr name="fmItemMargin" format="dimension"/>

// menu anchoring position (see below)
<attr name="fmMenuAnchor" format="string"/>

// margin around the menu - menu will be positioned this far away from the button, but 
// will also use this to respect screen edges
<attr name="fmMenuMargin" format="dimension"/>

// if provided, the trigger button will use this as a drawable
<attr name="fmButtonSrc" format="reference"/>

// elevation for the trigger button. if 0, no shadow is drawn
<attr name="fmButtonElevation" format="dimension"/>

// elevation for the menu. if 0, no shadow is drawn
<attr name="fmMenuElevation" format="dimension"/>

// if true, a shield (like for dialogs) is drawn behind the menu
<attr name="fmShieldVisible" format="boolean"/>

// color of shield drawn behind menu, if shieldVisible == true
<attr name="fmShieldColor" format="color"/>

// if true, menu operates in "tap to open", "tap to select and dismiss" mode
<attr name="fmDialogMode" format="boolean"/>

The fmMenuAnchor attribute takes the following values:

  • top : menu attached above the button
  • right | end : menu attached to right of button
  • bottom : menu attached beneath button
  • left | start : menu attached to left of button
  • center : menu centered on top of button

Java

To use a FlyoutMenuView, you must provide a FlyoutMenuView.Adapter (which provides FlyoutMenuView.MenuItem instances) and a FlyoutMenuView.Layout which describes how to position the items in the menu.

You must also provide a subclass of FlyoutMenuView.MenuItem to render your items. You may also subclass FlyoutMenuView.ButtonRenderer to render your trigger button, if you don't want to assign a Drawable.

Here's an example implementation of FlyoutMenuView.MenuItem and FlyoutmenuView.ButtonRenderer which draws a simple unicode character. I use it in the demo app to render emoji.

public class EmojiFlyoutMenu {

	static String getEmojiByUnicode(int unicode){
		return new String(Character.toChars(unicode));
	}

	public static class MenuItem extends FlyoutMenuView.MenuItem {

		int emojiCode;
		String emojiString;
		TextPaint textPaint;

		public MenuItem(int id, int emojiCode, float size, @ColorInt int color) {
			super(id);
			this.emojiCode = emojiCode;
			this.emojiString = getEmojiByUnicode(emojiCode);

			textPaint = new TextPaint();
			textPaint.setTextSize(size);
			textPaint.setTextAlign(Paint.Align.CENTER);
			textPaint.setStyle(Paint.Style.FILL);
			textPaint.setColor(color);
		}

		public int getEmojiCode() {
			return emojiCode;
		}

		@Override
		public void onDraw(Canvas canvas, RectF bounds, float degreeSelected) {
			canvas.drawText(emojiString, bounds.centerX(), bounds.centerY() - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
		}
	}

	public static class ButtonRenderer extends FlyoutMenuView.ButtonRenderer {

		int emojiCode;
		String emojiString;
		Paint paint;
		TextPaint textPaint;

		public ButtonRenderer(int emojiCode, float size, @ColorInt int color) {
			super();

			this.setEmojiCode(emojiCode);

			paint = new Paint();
			paint.setAntiAlias(true);

			textPaint = new TextPaint();
			textPaint.setTextSize(size);
			textPaint.setTextAlign(Paint.Align.CENTER);
			textPaint.setStyle(Paint.Style.FILL);
			textPaint.setColor(color);
		}

		public int getEmojiCode() {
			return emojiCode;
		}

		public void setEmojiCode(int emojiCode) {
			this.emojiCode = emojiCode;
			this.emojiString = getEmojiByUnicode(this.emojiCode);
		}

		@Override
		public void onDrawButtonContent(Canvas canvas, RectF buttonBounds, @ColorInt int buttonColor, float alpha) {
			textPaint.setAlpha((int) (alpha * 255f));
			canvas.drawText(emojiString, buttonBounds.centerX(), buttonBounds.centerY() - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
		}
	}
}

To use the above:

FlyoutMenuView smileyFlyoutMenu = findViewById(R.id.smileyFlyoutMenu); 

int[] emojiCodes = {
		0x1F60D, //smiling face heart shaped eyes
		0x1F605, // smiling face with open mouth and cold sweat
		0x1F60A, // smiling face
		0x1F613, // face with cold sweat
		0x1F61E, // disappointed face
		0x1F620, // angry face
		0x1F62D, // loudly crying face
		0x1F4A9, // pile of poo
};

@ColorInt int color = ContextCompat.getColor(this, R.color.smileyMenuCharColor);
float fontSizeInMenu = getResources().getDimension(R.dimen.smiley_menu_item_size) * 0.5f;
float fontSizeInButton = getResources().getDimension(R.dimen.flyout_menu_button_size) * 0.5f;

// build a List<> of EmojiFlyoutMenu.MenuItem
List<EmojiFlyoutMenu.MenuItem> menuItems = new ArrayList<>();
for (int code : emojiCodes) {
	menuItems.add(new EmojiFlyoutMenu.MenuItem(menuItems.size(), code, fontSizeInMenu, color));
}

// assign a GridLayout with 2 columns and unspecified rows (allows menu to grow vertically)
smileyFlyoutMenu.setLayout(new FlyoutMenuView.GridLayout(2, FlyoutMenuView.GridLayout.UNSPECIFIED));

// assign the menuItems via an ArrayAdapter
smileyFlyoutMenu.setAdapter(new FlyoutMenuView.ArrayAdapter<>(menuItems));

// create and assign the button renderer. we'll change the button renderer's emoji in the callback below
final EmojiFlyoutMenu.ButtonRenderer renderer = new EmojiFlyoutMenu.ButtonRenderer(emojiCodes[0], fontSizeInButton, color);
smileyFlyoutMenu.setButtonRenderer(renderer);

smileyFlyoutMenu.setSelectionListener(new FlyoutMenuView.SelectionListener() {
	@Override
	public void onItemSelected(FlyoutMenuView flyoutMenuView, FlyoutMenuView.MenuItem item) {
	
		// user has selected an item. update the button renderer's emoji to match
		renderer.setEmojiCode(((EmojiFlyoutMenu.MenuItem) item).getEmojiCode());
	}

	@Override
	public void onDismissWithoutSelection(FlyoutMenuView flyoutMenuView) {
	}
});
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].