自定义的巡航栏

下面为自定义的巡航栏的按钮

package com.huaiye.ecs.common.views.compass;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import java.util.Timer;
import java.util.TimerTask;

/**
 * author: admin
 * date: 2017/05/24
 * version: 0
 * mail: secret
 * desc: SpecialView
 */

public class ToyView extends ImageView {

    RectF mInnerRect;

    RectF mOuterRect;

    Path mTriangleArrow;

    Paint paint;

    int mTextColor = Color.parseColor("#333333");
    TextPaint mTextPaint;

    String mText = "巡航";

    PressListener mPressListener;

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

    public ToyView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public ToyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        Paint csp = new Paint();
        // Android5.0 解决裁剪完成之后其他区域为黑色的问题
        csp.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY));
        this.setLayerType(View.LAYER_TYPE_SOFTWARE, csp);

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);

        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setColor(mTextColor);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int r = getRadius();

        mOuterRect = new RectF(0, 0, r * 8 / 10, r * 8 / 10);

        mInnerRect = new RectF(0, 0, r * 1 / 2, r * 1 / 2);

        mTriangleArrow = new Path();

        mTextPaint.setTextSize(r * 0.14f);

        float density = getResources().getDisplayMetrics().density;

        float triangle1X = -3.5f * density;
        float triangle1Y = r / 10f + 2.5f * density;

        float triangle2X = 3.5f * density;
        float triangle2Y = r / 10f + 2.5f * density;

        float triangle3X = 0;
        float triangle3Y = r / 10f - 2.5f * density;

        mTriangleArrow.moveTo(triangle1X, triangle1Y);
        mTriangleArrow.quadTo(triangle1X, triangle1Y, triangle2X, triangle2Y);
        mTriangleArrow.quadTo(triangle2X, triangle2Y, triangle3X, triangle3Y);
        mTriangleArrow.quadTo(triangle3X, triangle3Y, triangle1X, triangle1Y);
        mTriangleArrow.close();
    }


    int getRadius() {
        return getMeasuredWidth() > getMeasuredHeight() ? getMaxHeight() : getMeasuredWidth();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int dist = getDistanceToCircleCenter(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                if(mPressingTimer != null){
                    mPressingTimer.cancel();
                    mPressingTimer = null;
                }

                if (dist < getRadius() * 3f / 10 - 10
                        || dist > getRadius() / 2f + 10) {

                    currentFocusIndex = -1;
                    postInvalidate();

                } else {

                    currentFocusIndex = getPressedItem(event);

                    if(mPressListener != null){
                        mPressingTimer = new Timer();
                        mPressingTimer.schedule(new ContinuePressTask(currentFocusIndex),0,360);
                    }
                    postInvalidate();
                }

                break;
            case MotionEvent.ACTION_MOVE:

                if (dist < getRadius() * 3f / 10 - 10
                        || dist > getRadius() / 2f + 10) {

                    if(mPressingTimer != null){
                        mPressingTimer.cancel();
                        mPressingTimer = null;
                    }

                    if(currentFocusIndex != -1){
                        currentFocusIndex = -1;
                        postInvalidate();
                    }

                } else {

                    int index = getPressedItem(event);
                    if(index != currentFocusIndex
                            && currentFocusIndex != -1){

                        if(mPressingTimer != null){
                            mPressingTimer.cancel();
                            mPressingTimer = null;
                        }

                        currentFocusIndex = -1;
                        postInvalidate();
                    }
                }

                break;
            case MotionEvent.ACTION_UP:

                if(mPressingTimer != null){
                    mPressingTimer.cancel();
                    mPressingTimer = null;
                }

                int item = getPressedItem(event);
                if(item == currentFocusIndex){
                    if(mPressListener != null){
                        mPressListener.onSingleTap(item);
                    }
                }

                currentFocusIndex = -1;
                postInvalidate();
                break;
        }

        return true;
    }

    float getDegree(MotionEvent event) {
        int c = getDistanceToCircleCenter(event);
        double a = event.getY() - getMeasuredHeight() / 2;
        double sin = a / c;
        if (sin < -1) {
            sin = -1;
        }
        if (sin > 1) {
            sin = 1;
        }

        float degree = (int) (Math.asin(sin) / Math.PI * 180);

        int quadrant = getQuadrant(event);

        switch (quadrant) {
            case 1:
                degree = 112.5f + degree;
                break;
            case 2:
                if (degree < -67.5) {
                    degree = degree + 112.5f;
                } else {
                    degree = 360 + degree + 22.5f;
                }

                break;
            case 3:
                degree = 180 - degree + 112.5f;
                break;
            case 4:
                if (degree < 0) {
                    degree = 90 + degree + 112.5f;
                } else {
                    degree += 112.5f;
                }

                break;
        }

        return degree;
    }

    int getPressedItem(MotionEvent event) {
        float degree = getDegree(event);

        int index = (int) Math.floor(degree / 45f);

        return index;
    }

    /**
     * 获取象限
     *
     * @param event
     * @return
     */
    int getQuadrant(MotionEvent event) {

        float centerX = getMeasuredWidth() / 2f;
        float centerY = getMeasuredHeight() / 2f;

        float x = event.getX();
        float y = event.getY();

        if (x >= centerX
                && y <= centerY) {
            return 1;
        } else if (x < centerX && y < centerY) {

            return 2;
        } else if (x >= centerX
                && y >= centerY) {

            return 4;
        } else {

            return 3;
        }
    }

    int getDistanceToCircleCenter(MotionEvent event) {

        int centerX = getMeasuredWidth() / 2;
        int centerY = getMeasuredHeight() / 2;

        int dist = (int) Math.sqrt(Math.pow(event.getX() - centerX, 2) + Math.pow(event.getY() - centerY, 2));
        return dist;
    }

    public void setPressListener(PressListener listener){
        this.mPressListener = listener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawOuterBtns(canvas);

        drawInnerBtns(canvas);
    }

    int currentFocusIndex = -1;

    int mCircleBarColor = Color.WHITE;
    int mCenterCircleColor = Color.WHITE;
    int mDividerColor = Color.parseColor("#cccccc");
    int mArrowColor = Color.parseColor("#333333");

    void drawOuterBtns(Canvas canvas) {

        int degree = 45;
        float hafDegree = 45f / 2;
        int radius = getRadius() / 5;
        int centerX = getMeasuredWidth() / 2;
        int centerY = getMeasuredHeight() / 2;

        canvas.save();
        canvas.translate((getMeasuredWidth() - mOuterRect.width()) / 2, (getMeasuredHeight() - mOuterRect.width()) / 2);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(radius);
        paint.setColor(mCircleBarColor);
        canvas.drawOval(mOuterRect, paint);
        canvas.restore();

        for (int i = 0; i < 8; i++) {
            // 画选中
            if (currentFocusIndex == i) {

                paint.setColor(mDividerColor);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(radius);

                canvas.save();
                canvas.rotate(degree * i - hafDegree, centerX, centerY);
                canvas.translate((getMeasuredWidth() - mOuterRect.width()) / 2, (getMeasuredHeight() - mOuterRect.width()) / 2);
                canvas.drawArc(mOuterRect, -90, degree, false, paint);
                canvas.restore();
            }

            // 画箭头
            canvas.save();
            canvas.rotate(degree * i, centerX, centerY);
            canvas.translate(getMeasuredWidth() / 2, 0);
            paint.setColor(mArrowColor);
            paint.setStyle(Paint.Style.FILL);
            canvas.drawPath(mTriangleArrow, paint);
            canvas.restore();

            // 画分界线
            paint.setColor(mDividerColor);
            paint.setStrokeWidth(1.4f);
            paint.setStyle(Paint.Style.STROKE);

            canvas.save();
            canvas.rotate(degree * i - hafDegree, centerX, centerY);
            canvas.drawLine(getMeasuredWidth() / 2, 0, getMeasuredWidth() / 2, radius, paint);

            canvas.rotate(degree, centerX, centerY);
            canvas.drawLine(getMeasuredWidth() / 2, 0, getMeasuredWidth() / 2, radius, paint);
            canvas.restore();
        }

    }

    void drawInnerBtns(Canvas canvas) {

        canvas.save();
        canvas.translate((getMeasuredWidth() - mInnerRect.width()) / 2, (getMeasuredHeight() - mInnerRect.width()) / 2);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(mCenterCircleColor);
        canvas.drawOval(mInnerRect, paint);
        canvas.restore();

        float cy = getMeasuredHeight() / 2f;
        float cx = getMeasuredWidth() /2f;
        Paint.FontMetrics fm = mTextPaint.getFontMetrics();
        cy = cy - (fm.top + fm.bottom) / 2f;
        canvas.drawText(mText, 0, mText.length(), cx, cy, mTextPaint);

        Log.e("Test", "cx "+cx+" cy "+cy);

    }

    public interface PressListener{

        void onPressing(int item);

        void onSingleTap(int item);

    }

    Timer mPressingTimer;

    class ContinuePressTask extends TimerTask {

        int item;

        public ContinuePressTask(int item){
            this.item = item;
        }

        @Override
        public void run() {
            if(mPressListener != null
                    && item == currentFocusIndex){

                mPressListener.onPressing(item);
            }
        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值