zoukankan      html  css  js  c++  java
  • 弧形菜单(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);
            }
        }
    }

    源码下载...

     

  • 相关阅读:
    pexpect模块
    Python正则表达式
    telnetlib
    paramiko
    threadpool和Queue
    logging
    Python异常
    Python迭代器
    程序员工资那么高,却从不炫富?网友回复让人“笑喷了”!
    小白到web前端工程师需要学习哪些知识?
  • 原文地址:https://www.cnblogs.com/xxdh/p/6645447.html
Copyright © 2011-2022 走看看