弧形菜單(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);
        }
    }
}

 

源碼下載...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM