Android Radial / Pie Menu

后端 未结 2 1293
清歌不尽
清歌不尽 2020-12-16 02:43

I am looking to create a radial menu in a game that I am writing. Is there a class or API included to assist with this or an open source solution?

Something like th

相关标签:
2条回答
  • 2020-12-16 03:26

    There's no built in API for such menus, however, there's at least two ways to do this

    1) Build a layout representing your "menu" and attach it to the "FrameLayout" at the root of your android view. By adjusting the positioning of the element just before you make it visible, you can move it around the scree. This method is a little "hacky", but it should work.

    2) Build a completely custom component, including your own drawing methods and onTouch events, and attach it to your view. This method is quite a bit more complex (you'll need to implement all of the drawing methods), but is also somewhat more general.

    In either case, remember that you'll need to consider how the radial menu functions when the user is using the trackball/d-pad.

    0 讨论(0)
  • 2020-12-16 03:36

    Below has the View class ondraw() method to Draw the Radial Menu..

        @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);
    
    }
    

    and also Manage the X,Y Cordinates on Touch Event to touch Item Menu

      @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;
    }
    

    enter image description here

    Hope above code to be helpful..

    0 讨论(0)
提交回复
热议问题