弧形菜单(Android)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了弧形菜单(Android)相关的知识,希望对你有一定的参考价值。

弧形菜单(Android)

 

前言:公司需求,自己写的一个弧形菜单!

 

效果:

 

技术分享

 

开发环境:AndroidStudio2.2.1+gradle-2.14.1

 

涉及知识:1.自定义控件,2.事件分发等

 

 

部分代码:

public class HomePageMenuLayout extends ViewGroup {


    private Context context;
    // 菜单项的文本
    private String[] mItemTexts = null;

    private int StatusHeight;//状态栏高度

    public HomePageMenuLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        StatusHeight = ScreenUtils.getStatusHeight(context);
    }


    /**
     * 设置布局的宽高,并策略menu item宽高
     */
    int resWidth = 0;
    int resHeight = 0;
    int mRadius = 0;

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        //布局宽高尺寸设置为屏幕尺寸
        //设置该布局的大小
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);

        /**
         * 根据传入的参数,分别获取测量模式和测量值
         */
        int width = MeasureSpec.getSize(widthMeasureSpec);
        resHeight = MeasureSpec.getSize(heightMeasureSpec);
        resWidth = MeasureSpec.getSize(widthMeasureSpec);

        // 获得半径
        mRadius = (int) (resHeight / 2 - 2 * StatusHeight);
        //设置item尺寸
        int childSize = (int) (mRadius * 1 / 2);
        // menu item测量模式--精确模式
        int childMode = MeasureSpec.EXACTLY;

        for (int i = 0; i < getChildCount(); i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == GONE) {
                continue;
            }
            // 计算menu item的尺寸;以及和设置好的模式,去对item进行测量
            int makeMeasureSpec = -1;
            makeMeasureSpec = MeasureSpec.makeMeasureSpec(childSize, childMode);
            child.measure(makeMeasureSpec, makeMeasureSpec);
        }

    }

    /**
     * item布局的角度
     */
    private int[] widthall = null;

    /**
     * 设置Item的位置:第一个参数1:该参数指出当前ViewGroup的尺寸或者位置是否发生了改变
     * 2.当期绘图光标横坐标位置
     * 3.当前绘图光标纵坐标位置
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int left, top;
        int cWidth = (int) (mRadius * 1 / 2);
        final int childCount = getChildCount();
        // 计算,中心点到menu item中心的距离
        float tmp = mRadius - cWidth / 2;
        // 遍历去设置menuitem的位置
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == GONE) {
                continue;
            }
            left = (int) (mRadius * Math.cos(Math.toRadians(widthall[i]))) - 65;
            top = (int) (mRadius - (resHeight / 2 - 2 * StatusHeight) * Math.sin(Math.toRadians(widthall[i])) - StatusHeight);
            child.layout(left, top, left + cWidth, top + cWidth);

        }

    }

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

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


    // 菜单的个数
    private int mMenuItemCount;

    /**
     * 设置菜单条目的图标和文本
     */
    public void setMenuItemIconsAndTexts(String[] mItemTexts) {
        this.mItemTexts = mItemTexts;
        this.mMenuItemCount = mItemTexts.length;
        resultAngle();
        addMenuItems();
    }

    private void resultAngle() {

        switch (this.mMenuItemCount) {
            case 3:
                widthall = Constants.ITEM3;
                break;
            case 4:
                widthall = Constants.ITEM4;
                break;
            case 5:
                widthall = Constants.ITEM5;
                break;
            case 6:
                widthall = Constants.ITEM6;
                break;
            case 7:
                widthall = Constants.ITEM7;
                break;
            case 8:
                widthall = Constants.ITEM8;
                break;
            case 9:
                widthall = Constants.ITEM9;
                break;
            case 10:
                widthall = Constants.ITEM10;
                break;
            default:
                break;

        }

    }


    /**
     * 设置菜单条目的图标和文本
     */
    public void setMenuItemIconsAndTexts() {
        addMenuItems();
    }

    private int mMenuItemLayoutId = R.layout.homepage_item_layout;


    /**
     * MenuItem的点击事件接口
     */
    private OnMenuItemClickListener mOnMenuItemClickListener;

    private float yPosition = 0;
    /**
     * 添加菜单项
     */
    private void addMenuItems() {
        LayoutInflater mInflater = LayoutInflater.from(getContext());

        /**
         * 根据用户设置的参数,初始化view
         */
        for (int i = 0; i < mMenuItemCount; i++) {
            final int j = i;
            View view = mInflater.inflate(mMenuItemLayoutId, this, false);

            final ImageView iv = (ImageView) view
                    .findViewById(R.id.homepage_pager1_item_img);
            final TextView tv = (TextView) view
                    .findViewById(R.id.homepage_pager1_item_tv);
            if (iv != null) {
                iv.setImageResource(R.mipmap.menu_ture);
            }
            if (tv != null) {
                tv.setText(mItemTexts[i]);
            }
            view.findViewById(R.id.homepage_item_layout).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {}
            });
            view.findViewById(R.id.homepage_item_layout).setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        yPosition = event.getY();//获取按下的位置
                        iv.setImageResource(R.mipmap.menu);
                    } else if (event.getAction() == MotionEvent.ACTION_UP) {
                        iv.setImageResource(R.mipmap.menu_ture);
                        float displacement = Math.abs(yPosition - event.getY());
                        //精确按下的位置做出响应
                        if (mOnMenuItemClickListener != null&&displacement<25) {
                            mOnMenuItemClickListener.itemClick(v,j);
                        }
                    } else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
                        iv.setImageResource(R.mipmap.menu_ture);
                    }
                    return true;
                }
            });
            addView(view);
        }
    }
}

 

源码下载...

 

以上是关于弧形菜单(Android)的主要内容,如果未能解决你的问题,请参考以下文章

如何用滚动制作弧形菜单?

安卓自定义半圆弧形菜单

安卓自定义半圆弧形菜单

弧形菜单2(动画渐入)Kotlin开发(附带java源码)

标签菜单android - 不正确的调用片段

在弧形android的边缘添加一个圆圈?