`

一个不错的ArcMenu

阅读更多
ArcMenu这种效果现在很多人都实现了



而且代码质量也不错

package com.example.zhy_arcmenu;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.OvershootInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

/**
 * 用法:
 *      arc_menu = (ArcMenu) findViewById(R.id.arc_menu);
        arc_menu.setOnMenuItemClickListener(new OnMenuItemClickListener()
        {
            @Override
            public void onClick(View view, int pos)
            {
            }
        });
        
        // 动态添加一个菜单项
        ImageView people = new ImageView(this);
        people.setImageResource(R.drawable.composer_with);
        people.setTag("People");
        arc_menu.addView(people);
        
   注意:ArcMenu中第一个元素必需叫handler,用于触发菜单显示或关闭;否则可能会报错;
 * @author zhy
 * 
 */
public class ArcMenu extends ViewGroup implements OnClickListener
{

    private static final String TAG = "ArcMenu";

    /**
     * 菜单的显示位置
     */
    private Position mPosition = Position.LEFT_TOP;

    /**
     * 菜单显示的半径,默认100dp
     */
    private int mRadius = 100;

    /**
     * 用户点击的按钮
     */
    private View mButton;

    /**
     * 当前ArcMenu的状态
     */
    private Status mCurrentStatus = Status.CLOSE;

    /**
     * 回调接口
     */
    private OnMenuItemClickListener onMenuItemClickListener;

    /**
     * 状态的枚举类
     * 
     * @author zhy
     * 
     */
    public enum Status
    {
        OPEN, CLOSE
    }

    /**
     * 设置菜单现实的位置,四选1,默认右下
     * 
     * @author zhy
     */
    public enum Position
    {
        LEFT_TOP, RIGHT_TOP, RIGHT_BOTTOM, LEFT_BOTTOM;
    }

    public interface OnMenuItemClickListener
    {
        void onClick(View view, int pos);
    }

    public ArcMenu(Context context)
    {
        this(context, null);
    }

    public ArcMenu(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);

    }

    /**
     * 初始化属性
     * 
     * @param context
     * @param attrs
     * @param defStyle
     */
    public ArcMenu(Context context, AttributeSet attrs, int defStyle)
    {

        super(context, attrs, defStyle);
        // dp convert to px
        mRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRadius, getResources().getDisplayMetrics());
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ArcMenu, defStyle, 0);

        int n = a.getIndexCount();
        for (int i = 0; i < n; i++)
        {
            int attr = a.getIndex(i);
            switch (attr)
            {
                case R.styleable.ArcMenu_position:
                    int val = a.getInt(attr, 0);
                    switch (val)
                    {
                        case 0:
                            mPosition = Position.LEFT_TOP;
                            break;
                        case 1:
                            mPosition = Position.RIGHT_TOP;
                            break;
                        case 2:
                            mPosition = Position.RIGHT_BOTTOM;
                            break;
                        case 3:
                            mPosition = Position.LEFT_BOTTOM;
                            break;
                    }
                    break;
                case R.styleable.ArcMenu_radius:
                    // dp convert to px
                    mRadius = a.getDimensionPixelSize(attr,
                        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100f, getResources().getDisplayMetrics()));
                    break;

            }
        }
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int count = getChildCount();
        for (int i = 0; i < count; i++)
        {
            // mesure child
            getChildAt(i).measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        if (changed)
        {

            layoutButton();
            int count = getChildCount();
            /**
             * 设置所有孩子的位置 例如(第一个为按钮): 左上时,从左到右 ] 第2个:mRadius(sin0 , cos0) 第3个:mRadius(sina ,cosa) 注:[a = Math.PI / 2 *
             * (cCount - 1)] 第4个:mRadius(sin2a ,cos2a) 第5个:mRadius(sin3a , cos3a) ...
             */
            for (int i = 0; i < count - 1; i++)
            {
                View child = getChildAt(i + 1);
                child.setVisibility(View.GONE);

                int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));
                int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));
                // childview width
                int cWidth = child.getMeasuredWidth();
                // childview height
                int cHeight = child.getMeasuredHeight();

                // 右上,右下
                if (mPosition == Position.LEFT_BOTTOM || mPosition == Position.RIGHT_BOTTOM)
                {
                    ct = getMeasuredHeight() - cHeight - ct;
                }
                // 右上,右下
                if (mPosition == Position.RIGHT_TOP || mPosition == Position.RIGHT_BOTTOM)
                {
                    cl = getMeasuredWidth() - cWidth - cl;
                }

                Log.e(TAG, cl + " , " + ct);
                child.layout(cl, ct, cl + cWidth, ct + cHeight);

            }
        }
    }

    /**
     * 第一个子元素为按钮,为按钮布局且初始化点击事件
     */
    private void layoutButton()
    {
        View cButton = getChildAt(0);

        cButton.setOnClickListener(this);

        int l = 0;
        int t = 0;
        int width = cButton.getMeasuredWidth();
        int height = cButton.getMeasuredHeight();
        switch (mPosition)
        {
            case LEFT_TOP:
                l = 0;
                t = 0;
                break;
            case LEFT_BOTTOM:
                l = 0;
                t = getMeasuredHeight() - height;
                break;
            case RIGHT_TOP:
                l = getMeasuredWidth() - width;
                t = 0;
                break;
            case RIGHT_BOTTOM:
                l = getMeasuredWidth() - width;
                t = getMeasuredHeight() - height;
                break;

        }
        Log.e(TAG, l + " , " + t + " , " + (l + width) + " , " + (t + height));
        cButton.layout(l, t, l + width, t + height);

    }

    /**
     * 为按钮添加点击事件
     */
    @Override
    public void onClick(View v)
    {
        // ArcMenu中第一个元素必需叫handler,用于触发菜单显示或关闭;
        // 否则这里可能会报错;
        mButton = findViewById(R.id.handler);
        if (mButton == null)
        {
            mButton = getChildAt(0);
        }
        rotateView(mButton, 0f, 270f, 300);
        toggleMenu(300);
    }

    /**
     * 按钮的旋转动画
     * 
     * @param view
     * @param fromDegrees
     * @param toDegrees
     * @param durationMillis
     */
    public static void rotateView(View view, float fromDegrees, float toDegrees, int durationMillis)
    {
        RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotate.setDuration(durationMillis);
        rotate.setFillAfter(true);
        view.startAnimation(rotate);
    }

    public void toggleMenu(int durationMillis)
    {
        int count = getChildCount();
        for (int i = 0; i < count - 1; i++)
        {
            final View childView = getChildAt(i + 1);
            childView.setVisibility(View.VISIBLE);

            int xflag = 1;
            int yflag = 1;

            if (mPosition == Position.LEFT_TOP || mPosition == Position.LEFT_BOTTOM)
                xflag = -1;
            if (mPosition == Position.LEFT_TOP || mPosition == Position.RIGHT_TOP)
                yflag = -1;

            // child left
            int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));
            // child top
            int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));

            AnimationSet animset = new AnimationSet(true);
            Animation animation = null;
            if (mCurrentStatus == Status.CLOSE)
            {// to open
                animset.setInterpolator(new OvershootInterpolator(2F));
                animation = new TranslateAnimation(xflag * cl, 0, yflag * ct, 0);
                childView.setClickable(true);
                childView.setFocusable(true);
            }
            else
            {// to close
                animation = new TranslateAnimation(0f, xflag * cl, 0f, yflag * ct);
                childView.setClickable(false);
                childView.setFocusable(false);
            }
            animation.setAnimationListener(new AnimationListener()
            {
                public void onAnimationStart(Animation animation)
                {
                }

                public void onAnimationRepeat(Animation animation)
                {
                }

                public void onAnimationEnd(Animation animation)
                {
                    if (mCurrentStatus == Status.CLOSE)
                        childView.setVisibility(View.GONE);

                }
            });

            animation.setFillAfter(true);
            animation.setDuration(durationMillis);
            // 为动画设置一个开始延迟时间,纯属好看,可以不设
            animation.setStartOffset((i * 100) / (count - 1));
            RotateAnimation rotate = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rotate.setDuration(durationMillis);
            rotate.setFillAfter(true);
            animset.addAnimation(rotate);
            animset.addAnimation(animation);
            childView.startAnimation(animset);
            final int index = i + 1;
            childView.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    if (onMenuItemClickListener != null)
                        onMenuItemClickListener.onClick(childView, index - 1);
                    menuItemAnin(index - 1);
                    changeStatus();

                }
            });

        }
        changeStatus();
        Log.e(TAG, mCurrentStatus.name() + "");
    }

    private void changeStatus()
    {
        mCurrentStatus = (mCurrentStatus == Status.CLOSE ? Status.OPEN : Status.CLOSE);
    }

    /**
     * 开始菜单动画,点击的MenuItem放大消失,其他的缩小消失
     * 
     * @param item
     */
    private void menuItemAnin(int item)
    {
        for (int i = 0; i < getChildCount() - 1; i++)
        {
            View childView = getChildAt(i + 1);
            if (i == item)
            {
                childView.startAnimation(scaleBigAnim(300));
            }
            else
            {
                childView.startAnimation(scaleSmallAnim(300));
            }
            childView.setClickable(false);
            childView.setFocusable(false);

        }

    }

    /**
     * 缩小消失
     * 
     * @param durationMillis
     * @return
     */
    private Animation scaleSmallAnim(int durationMillis)
    {
        Animation anim = new ScaleAnimation(1.0f, 0f, 1.0f, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        anim.setDuration(durationMillis);
        anim.setFillAfter(true);
        return anim;
    }

    /**
     * 放大,透明度降低
     * 
     * @param durationMillis
     * @return
     */
    private Animation scaleBigAnim(int durationMillis)
    {
        AnimationSet animationset = new AnimationSet(true);

        Animation anim = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        Animation alphaAnimation = new AlphaAnimation(1, 0);
        animationset.addAnimation(anim);
        animationset.addAnimation(alphaAnimation);
        animationset.setDuration(durationMillis);
        animationset.setFillAfter(true);
        return animationset;
    }

    public Position getmPosition()
    {
        return mPosition;
    }

    public void setmPosition(Position mPosition)
    {
        this.mPosition = mPosition;
    }

    public int getmRadius()
    {
        return mRadius;
    }

    public void setmRadius(int mRadius)
    {
        this.mRadius = mRadius;
    }

    public Status getmCurrentStatus()
    {
        return mCurrentStatus;
    }

    public void setmCurrentStatus(Status mCurrentStatus)
    {
        this.mCurrentStatus = mCurrentStatus;
    }

    public OnMenuItemClickListener getOnMenuItemClickListener()
    {
        return onMenuItemClickListener;
    }

    public void setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener)
    {
        this.onMenuItemClickListener = onMenuItemClickListener;
    }

}


自定义属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="position">
        <enum name="left_top" value="0" />
        <enum name="right_top" value="1" />
        <enum name="right_bottom" value="2" />
        <enum name="left_bottom" value="3" />
    </attr>
    <attr name="radius" format="dimension"></attr>

    <declare-styleable name="ArcMenu">
        <attr name="position" />
        <attr name="radius"/>
    </declare-styleable>

</resources>


用法:
package com.example.zhy_arcmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.zhy_arcmenu.ArcMenu.OnMenuItemClickListener;

/**
 * Android 自定义ViewGroup手把手教你实现ArcMenu http://blog.csdn.net/lmj623565791/article/details/37567907
 * 
 */
public class MainActivity extends Activity
{

    private ArcMenu arc_menu_left_top;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        arc_menu_left_top = (ArcMenu) findViewById(R.id.arc_menu_left_top);

        // 动态添加一个菜单项
        ImageView people = new ImageView(this);
        people.setImageResource(R.drawable.composer_with);
        people.setTag("People");
        arc_menu_left_top.addView(people);

        arc_menu_left_top.setOnMenuItemClickListener(new OnMenuItemClickListener()
        {
            @Override
            public void onClick(View view, int pos)
            {
                Toast.makeText(MainActivity.this, pos + ":" + view.getTag(), Toast.LENGTH_SHORT).show();
            }
        });
    }

}



布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_arcmenu"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.zhy_arcmenu.ArcMenu
        android:id="@+id/arc_menu_left_top"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        zhy:position="left_top"
        zhy:radius="130dp" >

        <ImageView
            android:id="@+id/handler"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@drawable/composer_button"
            android:scaleType="center"
            android:src="@drawable/composer_icn_plus" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_camera"
            android:tag="Camera" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sun"
            android:tag="Sun" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_place"
            android:tag="Place" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sleep"
            android:tag="Sleep" />
    </com.example.zhy_arcmenu.ArcMenu>

    <com.example.zhy_arcmenu.ArcMenu
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        zhy:position="right_bottom"
        zhy:radius="130dp" >

        <!-- 如果没有id,默认会将第一个元素作为handler -->
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/composer_button" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:src="@drawable/composer_icn_plus" />
        </RelativeLayout>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_camera"
            android:tag="Camera" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sun"
            android:tag="Sun" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_place"
            android:tag="Place" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sleep"
            android:tag="Sleep" />
    </com.example.zhy_arcmenu.ArcMenu>

    <com.example.zhy_arcmenu.ArcMenu
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        zhy:position="left_bottom"
        zhy:radius="130dp" >

        <!-- 如果没有id,默认会将第一个元素作为handler -->
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/composer_button" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:src="@drawable/composer_icn_plus" />
        </RelativeLayout>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sun"
            android:tag="Sun" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_place"
            android:tag="Place" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sleep"
            android:tag="Sleep" />
    </com.example.zhy_arcmenu.ArcMenu>

    <com.example.zhy_arcmenu.ArcMenu
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        zhy:position="right_top"
        zhy:radius="130dp" >

        <!-- 如果没有id,默认会将第一个元素作为handler -->
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/composer_button" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:src="@drawable/composer_icn_plus" />
        </RelativeLayout>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_camera"
            android:tag="Camera" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sun"
            android:tag="Sun" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_place"
            android:tag="Place" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/composer_sleep"
            android:tag="Sleep" />
    </com.example.zhy_arcmenu.ArcMenu>

</RelativeLayout>



Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单
http://blog.csdn.net/lmj623565791/article/details/43131133

Android的一个非常简单的弧形布局库:ArcLayout
http://www.open-open.com/lib/view/open1427963090693.html

Android库:ExpandableSelector
http://www.open-open.com/lib/view/open1434528013192.html
  • 大小: 253 KB
分享到:
评论

相关推荐

    ArcMenu(底部)

    总的来说,ArcMenu(底部)是一个富有创意的界面元素,它结合了美观和实用性,为移动应用的菜单设计提供了新的思路。开发者需要具备扎实的Android UI编程基础,熟悉自定义ViewGroup的实现,以及对动画和手势识别的理解...

    自定义ArcMenu

    【自定义ArcMenu】是一种在Android平台上实现的独特交互式菜单设计,它允许开发者创建一个位置可定制、动画效果丰富的卫星菜单。这个自定义组件通常用于应用程序中,为用户提供一种新颖的方式来展示和选择功能或选项...

    android ArcMenu

    【Android ArcMenu】是一个专为Android平台设计的自定义视图组件,它的灵感来源于ISO版本的Path2.0应用程序中的菜单样式。ArcMenu提供了一种独特的方式来展示菜单项,即在用户点击某个触发按钮后,菜单项以弧形的...

    ArcMenu——Github上找到的一个超赞的Menu开源控件

    【ArcMenu——一款创新的...对于希望在UI设计上寻求突破的开发者来说,ArcMenu无疑是一个值得尝试的优秀开源项目。通过深入学习和实践,开发者可以将其潜力充分挖掘,为自己的应用打造出独特而吸引人的界面元素。

    Android应用源码ArcMenu.zip

    整个菜单由一个中心按钮和围绕中心按钮的多个子菜单项组成。中心按钮通常用于触发菜单的显示和隐藏,而子菜单项则包含实际的功能或操作。 2. **手势识别与处理**: ArcMenu识别用户的滑动手势,当用户在屏幕上的...

    Android-ArcMenu弧形菜单kotlin实现

    2. **设计布局**:在`res/layout`目录下,创建一个新的XML布局文件来定义`ArcMenu`的结构。你需要一个中心按钮(通常为ImageView或Button)以及多个子菜单项(可以是`MenuItem`或自定义视图)。每个子菜单项需要设置...

    Android自定义ViewGroup完美实现 ArcMenu

    ArcMenu是一个非常吸引人的设计,它呈现了一个扇形的菜单布局,通常用于显示一些可点击的图标或者选项,这种设计通常会给人一种优雅而直观的交互体验。本文将深入探讨如何在Android中完美实现ArcMenu,并结合提供的...

    ArcMenu仿path按钮.rar

    【ArcMenu仿path按钮】是一个Android开发中的设计资源,它主要实现了类似Path应用中的菜单动画效果。这个压缩包包含两个主要部分:ArcMenuLib和ArcMenu。这些文件旨在帮助开发者在自己的应用程序中创建一个优雅且...

    Floating-ArcMenu, 所有应用程序的prety菜单.zip

    Floating-ArcMenu, 所有应用程序的prety菜单 浮动 arcmenu为所有应用程序 prety菜单中新特性的特性向ArcMenu和FloatActionButton添加了SnackBar向上/向下事件( 通过使用CoordinatorLayout作为父级)以编程

    ArcMenu仿path按钮.zip

    《ArcMenu:一款灵感源自Path应用的Android菜单设计》 ArcMenu是一款专为Android平台设计的菜单组件,其设计灵感来源于知名的社交应用Path。这款组件以其独特的弧形展开方式,为用户提供了新颖且直观的交互体验,...

    android ArcMenu仿path按钮源码.rar

    ArcMenu 通常由一个主按钮(通常是一个图标)和一组围绕主按钮展开的子菜单项组成。当用户点击主按钮时,子菜单项会以弧形轨迹展开或收起。这一过程涉及到布局设计、动画控制以及事件处理等多个方面。 2. **源码...

    应用源码ArcMenu.zip

    通过对ArcMenu源码的分析,我们可以了解到如何在Android中实现优雅的动画效果,以及如何设计并实现一个可扩展的组件。 在Android应用开发中,源码学习是一种非常有效的提升技能的方式。通过阅读和理解ArcMenu的源码...

    ArcMenu-path菜单master.zip

    ArcMenu的设计理念是将菜单项沿着一个弧形轨迹展开,这种动态的展示方式不仅美观,还能在有限的屏幕空间内展示更多的功能,从而提升应用程序的用户体验。 一、ArcMenu的基本结构与原理 ArcMenu的核心在于其自定义...

    安卓Android源码——ArcMenu-path菜单master.zip

    ArcMenu是一个Android库项目,它允许开发者在界面上添加一个弧形弹出的菜单,增加了操作的趣味性和便捷性。这个开源项目,即ArcMenu,是一个基于Path和Canvas的自定义视图,通过它可以创建动态展开的弧形菜单,为...

    android ArcMenu-path菜单源码.zip

    菜单项是通过`ArcMenu.addMenuItem()`方法添加的,这个方法接收一个`MenuItem`对象作为参数。`MenuItem`对象包含了文字、图标等信息,以及点击事件的监听器。 5. **触摸事件处理** ArcMenu的触摸事件处理主要在`...

    ArcMenu-path菜单master.rar

    【ArcMenu-path菜单master】是一个开源项目,主要关注于Android平台上的自定义菜单实现。这个项目的核心在于提供一种独特且可定制化的菜单展示方式,它可能是为了增强用户体验或者在有限的屏幕空间内提供更多的操作...

Global site tag (gtag.js) - Google Analytics