最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
FlyoutMenus:实践指南
时间:2026-09-10 19:04:01 编辑:袖梨 来源:一聚教程网
如果把FlyoutMenus放进候选清单,不能只看热度;它的定位是适用于 Android 的简单材质风格弹出菜单, Android 有很多弹出式菜单,但这个是我的。团队若要把它用于日常自动化,应先处理输入边界、依赖和失败处理如果不清楚就很难稳定复用,否则试用结果很容易失真。我的评估方法是用一项范围明确的真实任务完成最小试跑,然后检查配置时间、输出质量、异常信息和维护痕迹是否与文档一致。如果团队属于愿意先做小范围验证并复查原始文档的团队,它有继续测试的理由;否则先看替代方案会更省时间。
FlyoutMenus
适用于 Android 的简单材质风格弹出菜单。 Android 有很多弹出式菜单,但这个是我的。
compile 'org.zakariya.flyoutmenus:flyoutmenu:0.5.3'
- minSdkVersion: 14 注意:在小于 18 的 SDK 上运行时,硬件渲染被禁用。这意味着按钮阴影被剪裁。要解决此问题,请向视图添加一些填充。
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 属性(均具有 fm 前缀)为:
// 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"/>
fmMenuAnchor 属性采用以下值:
top:按钮上方附加菜单right|end:菜单附加到按钮右侧bottom:菜单附加在按钮下方left|start:菜单附加到按钮左侧center:菜单位于按钮顶部中心
爪哇
要使用 FlyoutMenuView,您必须提供 FlyoutMenuView.Adapter(提供 FlyoutMenuView.MenuItem 实例)和 FlyoutMenuView.Layout(描述如何在菜单中定位项目)。
您还必须提供 FlyoutMenuView.MenuItem 的子类来呈现您的项目。如果您不想分配 Drawable,您还可以子类化 FlyoutMenuView.ButtonRenderer 来呈现触发按钮。
下面是 FlyoutMenuView.MenuItem 和 FlyoutmenuView.ButtonRenderer 的示例实现,它绘制了一个简单的 unicode 字符。我在演示应用程序中使用它来渲染表情符号。
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);
}
}
}
要使用上面的内容:
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) {
}
});
相关文章
- TrackMeNot:实践指南 09-10
- 哪个csgo饰品交易平台好有哪些重点-关键信息和实际影响 09-10
- Dex:实践指南 09-10
- 原神抽哥伦比娅还是抽伊涅芙有哪些重点-关键信息和实际影响 09-10
- hand-drawn-video-prompts:实践指南 09-10
- ha-evcc:实践指南 09-10