安卓环形菜单 / 饼状菜单

9

我正在编写一个游戏,希望创建一个径向菜单。是否有包含此功能的类或API,或者有开源解决方案可供使用?

就像这样

谢谢, Jake

2个回答

4
以下是View类的ondraw()方法,用于绘制径向菜单。
    @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mRadialMenuPaint.setShadowLayer(mShadowRadius, 0.0f, 0.0f, mShadowColor);  
    //Draw the menu if the menu is to be displayed.
    if(isMenuVisible) {
        canvas.drawArc(mMenuRect, mStartAngle, 180, true, mRadialMenuPaint);
        //See if there is any item in the collection
        if(mMenuItems.size() > 0) {
            float mStart = mStartAngle;
            //Get the sweep angles based on the number of menu items
            float mSweep = 180/mMenuItems.size();
            for(SemiCircularRadialMenuItem item : mMenuItems.values()) {
                mRadialMenuPaint.setColor(item.getBackgroundColor());
                item.setMenuPath(mMenuCenterButtonRect, mMenuRect, mStart, mSweep, mRadius, mViewAnchorPoints);
                canvas.drawPath(item.getMenuPath(), mRadialMenuPaint);
                if(isShowMenuText) {
                    mRadialMenuPaint.setShadowLayer(mShadowRadius, 0.0f, 0.0f, Color.TRANSPARENT);  
                    mRadialMenuPaint.setColor(item.getTextColor());
                    canvas.drawTextOnPath(item.getText(), item.getMenuPath(), 5, textSize, mRadialMenuPaint);
                    mRadialMenuPaint.setShadowLayer(mShadowRadius, 0.0f, 0.0f, mShadowColor);
                }
                item.getIcon().draw(canvas);
                mStart += mSweep;
            }
            mRadialMenuPaint.setStyle(Style.FILL);
        }
    }
    //Draw the center menu toggle piece
    mRadialMenuPaint.setColor(centerRadialColor);
    canvas.drawArc(mMenuCenterButtonRect, mStartAngle, 180, true, mRadialMenuPaint);
    mRadialMenuPaint.setShadowLayer(mShadowRadius, 0.0f, 0.0f, Color.TRANSPARENT);  
    //Draw the center text
    drawCenterText(canvas, mRadialMenuPaint);

}

并且,在触摸事件中管理X,Y坐标以触摸项目菜单。

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        if(mMenuCenterButtonRect.contains(x, y-15)) {
            centerRadialColor = RadialMenuColors.HOLO_LIGHT_BLUE;
            isMenuTogglePressed = true;
            invalidate();
        }
        else if(isMenuVisible) {
            if(mMenuItems.size() > 0) {
                for(SemiCircularRadialMenuItem item : mMenuItems.values()) {
                    if(mMenuRect.contains((int) x+20, (int) y))
                        if(item.getBounds().contains((int) x+20, (int) y)) {
                            System.out.println("get x...> " + x);
                            System.out.println("get y...> " + y);
                            isMenuItemPressed = true;
                            mPressedMenuItemID = item.getMenuID();
                            break;
                        }
                }
                mMenuItems.get(mPressedMenuItemID).setBackgroundColor(mMenuItems.get(mPressedMenuItemID).getMenuSelectedColor());
                invalidate();
            }
        }
        break;
    case MotionEvent.ACTION_UP:
        if(isMenuTogglePressed) {
            centerRadialColor = Color.WHITE;
            if(isMenuVisible) {
                isMenuVisible = false;
                centerMenuText = openMenuText;
            } else {
                isMenuVisible = true;
                centerMenuText = closeMenuText;
            }
            isMenuTogglePressed = false;
            invalidate();
        }

        if(isMenuItemPressed) {
            if(mMenuItems.get(mPressedMenuItemID).getCallback() != null) {
                mMenuItems.get(mPressedMenuItemID).getCallback().onMenuItemPressed();
            }
            mMenuItems.get(mPressedMenuItemID)
                .setBackgroundColor(mMenuItems.get(mPressedMenuItemID).getMenuNormalColor());
            isMenuItemPressed = false;
            invalidate();
        }
        break;
    }

    return true;
}

在此输入图片描述

希望上述代码对您有所帮助。


请问您能否定义变量类型,至少过去完整的视图类。谢谢您的提前帮助。 - Qadir Hussain

2
没有针对这种菜单的内置API,但是至少有两种方法可以实现此功能:
1)构建一个表示您的“菜单”的布局,并将其附加到Android视图根处的“FrameLayout”上。通过在使其可见之前调整元素的定位,您可以将其移动到屏幕周围。这种方法有点“hacky”,但应该可以工作。
2)构建完全自定义的组件,包括您自己的绘图方法和onTouch事件,并将其附加到您的视图上。这种方法更加复杂(您需要实现所有绘图方法),但也更加通用。
在任一情况下,请记住,在用户使用轨迹球/ D-pad时,您需要考虑径向菜单的功能。

这正是我所假设的,但我希望自定义组件已经存在。感谢您提供的信息。 - Jacob Hulse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接