Android自定义视图值选择器滑块我想在每个圆圈上方绘制文本作为标签

时间:2016-09-25 10:57:13

标签: android android-view android-custom-view

您好我已经创建了自定义视图"数字栏"这工作正常。我只想在每个指标上添加标签。我尝试了但是当我绘制文本时它是不可见的,因为视图没有达到高度。请查看下面的图片,谢谢。

enter image description here

查看onDraw源代码

protected void onDraw(Canvas canvas) {

        int indicatorWidthHeight = Utils.dpToPx(getContext(), indicatorSize);
        indicatorRadius = indicatorWidthHeight / 2;
        int cx = indicatorWidthHeight / 2;
        int cy = indicatorWidthHeight / 2;

        int totalIndicators =  5;
        int totalLines = totalIndicators - 1;

        int lineWidth = (getMeasuredWidth() - (indicatorWidthHeight * totalIndicators)) / totalLines;
        linePaint.setStrokeWidth(Utils.dpToPx(getContext(), lineHeight));

        for (int i = 0; i < circles.length; i++) {
            if (selected >= i) {
                indicatorPaint.setColor(selectedBackgroundColor);
                textPaint.setColor(selectedTextColor);
            } else {
                indicatorPaint.setColor(backgroundColor);
                textPaint.setColor(textColor);
            }
            if (selected >= i + 1) {
                linePaint.setColor(selectedBackgroundColor);
            } else {
                linePaint.setColor(backgroundColor);
            }
            int nCx = cx + (lineWidth + indicatorRadius * 2) * i;
            circles[i].setRadius(indicatorRadius);
            circles[i].setX(nCx);
            circles[i].setY(cy);
            canvas.drawCircle(nCx, cy, indicatorRadius, indicatorPaint);
            String text = "" + (i+1);
            textPaint.getTextBounds(text, 0, text.length(), rect);
            canvas.drawText(text, nCx, cy+rect.height()/2, textPaint);

//            Draw lines one less than circles
            if (i != circles.length - 1) {
                int startX = nCx + indicatorRadius;
                int stopX = nCx + indicatorRadius + lineWidth;
                lines[i].setStartX(startX);
                lines[i].setStartY(cy);
                lines[i].setStopX(stopX);
                lines[i].setStopY(cy);
                canvas.drawLine(startX, cy, stopX, cy, linePaint);
            }
        }
    }

查看完整源代码

public class NumberBar extends View {
    public static final int DEFAULT_TEXT_SIZE = 16;
    public static final int DEF_INDICATOR_SIZE = 20;
    Rect rect = new Rect();
    Circle[] circles = new Circle[5];
    Line[] lines = new Line[4];
    private int backgroundColor, textColor, selectedBackgroundColor, selectedTextColor, indicatorSize, lineHeight, selected;
    private Paint indicatorPaint;
    private Paint textPaint;
    private Paint linePaint;
    private int indicatorRadius;
    private boolean enabled = true;

    public NumberBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberBar, 0, 0);
        try {
            backgroundColor = typedArray.getInteger(R.styleable.NumberBar_backgroundColor, Color.parseColor("#eeeeee"));
            selectedBackgroundColor = typedArray.getInteger(R.styleable.NumberBar_selectedBackgroundColor, Color.parseColor("#0171fe"));
            textColor = typedArray.getInteger(R.styleable.NumberBar_textColor, Color.parseColor("#c8c8c8"));
            selectedTextColor = typedArray.getInteger(R.styleable.NumberBar_selectedTextColor, Color.parseColor("#ffffff"));
            indicatorSize = typedArray.getInteger(R.styleable.NumberBar_indicatorSize, DEF_INDICATOR_SIZE);
            lineHeight = typedArray.getInteger(R.styleable.NumberBar_lineHeight, 3);
            selected = typedArray.getInteger(R.styleable.NumberBar_selected, 0);
            enabled = typedArray.getBoolean(R.styleable.NumberBar_enabled, true);
        } finally {
            typedArray.recycle();
        }

        for (int i = 0; i < circles.length; i++) {
            circles[i] = new Circle();
        }

        for (int i = 0; i < lines.length; i++) {
            lines[i] = new Line();
        }

        indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        indicatorPaint.setStyle(Paint.Style.FILL);

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(Utils.spToPx(getContext(), DEFAULT_TEXT_SIZE));

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        int indicatorWidthHeight = Utils.dpToPx(getContext(), indicatorSize);
        indicatorRadius = indicatorWidthHeight / 2;
        int cx = indicatorWidthHeight / 2;
        int cy = indicatorWidthHeight / 2;

        int totalIndicators =  5;
        int totalLines = totalIndicators - 1;

        int lineWidth = (getMeasuredWidth() - (indicatorWidthHeight * totalIndicators)) / totalLines;
        linePaint.setStrokeWidth(Utils.dpToPx(getContext(), lineHeight));

        for (int i = 0; i < circles.length; i++) {
            if (selected >= i) {
                indicatorPaint.setColor(selectedBackgroundColor);
                textPaint.setColor(selectedTextColor);
            } else {
                indicatorPaint.setColor(backgroundColor);
                textPaint.setColor(textColor);
            }
            if (selected >= i + 1) {
                linePaint.setColor(selectedBackgroundColor);
            } else {
                linePaint.setColor(backgroundColor);
            }
            int nCx = cx + (lineWidth + indicatorRadius * 2) * i;
            circles[i].setRadius(indicatorRadius);
            circles[i].setX(nCx);
            circles[i].setY(cy);
            canvas.drawCircle(nCx, cy, indicatorRadius, indicatorPaint);
            String text = "" + (i+1);
            textPaint.getTextBounds(text, 0, text.length(), rect);
            canvas.drawText(text, nCx, cy+rect.height()/2, textPaint);

//            Draw lines one less than circles
            if (i != circles.length - 1) {
                int startX = nCx + indicatorRadius;
                int stopX = nCx + indicatorRadius + lineWidth;
                lines[i].setStartX(startX);
                lines[i].setStartY(cy);
                lines[i].setStopX(stopX);
                lines[i].setStopY(cy);
                canvas.drawLine(startX, cy, stopX, cy, linePaint);
            }
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!enabled) {
            return true;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                handleDownTouch(event.getX(), event.getY());
                break;
        }
        return true;
    }

    private void handleDownTouch(float eventX, float eventY) {
        for (int i = 0; i < circles.length; i++) {
            if (isCircleClicked(eventX, eventY, circles[i])) { //                Toast.makeText(NumberBar.this.getContext(), "Circle Clicked: " + i, Toast.LENGTH_SHORT).show();
                this.selected = i;
                invalidate();
                return;
            }
        }


        for (int i = 0; i < lines.length; i++) {
            if (inLine(lines[i].getStartPoint(), lines[i].getStopPoint(), new Point((int)eventX, (int)eventY))) {
                this.selected = i+1;
                invalidate();
                return; //                Toast.makeText(NumberBar.this.getContext(), "Line: " + i, Toast.LENGTH_SHORT).show();
            }
        }
    }

    // is BC inline with AC or visa-versa
    public boolean inLine(Point A, Point B, Point C) {
        int offset = 5;
        return C.x >= A.x && C.x <= B.x && (C.y <= (B.y-lineHeight+ offset) || C.y <= (B.y-lineHeight- offset));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //        Don't measure width its most or which user will give
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int height;

        //Measure Height
        if (heightMode == MeasureSpec.EXACTLY) {
            //Must be this size
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            //Can't be bigger than...
            height = Math.min(indicatorSize, heightSize);
        } else {
            //Be whatever you want
            height = indicatorSize;
        }

        //MUST CALL THIS
        setMeasuredDimension(widthSize, height);

        setMeasuredDimension(getMeasuredWidth(), Utils.dpToPx(getContext(), indicatorSize));
    }

    private boolean isCircleClicked(float ex, float ey, Circle circle) {
        return Math.sqrt((circle.getX() - ex) * (circle.getX() - ex) + (circle.getY() - ey) * (circle.getY() - ey)) < circle.getRadius()+4;
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    @Override
    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
        invalidate();
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
        invalidate();
    }

    public int getSelectedBackgroundColor() {
        return selectedBackgroundColor;
    }

    public void setSelectedBackgroundColor(int selectedBackgroundColor) {
        this.selectedBackgroundColor = selectedBackgroundColor;
        invalidate();
    }

    public int getSelectedTextColor() {
        return selectedTextColor;
    }

    public void setSelectedTextColor(int selectedTextColor) {
        this.selectedTextColor = selectedTextColor;
        invalidate();
    }

    public int getIndicatorSize() {
        return indicatorSize;
    }

    public void setIndicatorSize(int indicatorSize) {
        this.indicatorSize = indicatorSize;
        invalidate();
        requestLayout();
    }

    public int getLineHeight() {
        return lineHeight;
    }

    public void setLineHeight(int lineHeight) {
        this.lineHeight = lineHeight;
        invalidate();
        requestLayout();
    }

    public int getSelected() {
        return selected;
    }

    public void setSelected(int selected) {
        this.selected = selected;
        invalidate();
    }

    private class Circle {
        int x, y;
        int radius;

        public Circle() {
        }

        public Circle(int x, int y, int radius) {
            this.x = x;
            this.y = y;
            this.radius = radius;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }

        public int getRadius() {
            return radius;
        }

        public void setRadius(int radius) {
            this.radius = radius;
        }
    }

    class Line {
        Point startPoint = new Point();
        Point stopPoint = new Point();

        public int getStartX() {
            return startPoint.x;
        }

        public void setStartX(int startX) {
            this.startPoint.x = startX;
        }

        public int getStartY() {
            return startPoint.y;
        }

        public void setStartY(int startY) {
            this.startPoint.y = startY;
        }

        public int getStopX() {
            return stopPoint.x;
        }

        public void setStopX(int stopX) {
            this.stopPoint.x = stopX;
        }

        public int getStopY() {
            return stopPoint.y;
        }

        public void setStopY(int stopY) {
            this.stopPoint.y = stopY;
        }

        public Point getStartPoint() {
            return startPoint;
        }

        public Point getStopPoint() {
            return stopPoint;
        }
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    } }

0 个答案:

没有答案