import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Shader;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.View;import com.careeach.sport.R;import java.util.List;/** * 心率热图 */public class HeartRateView extends View {    private List values;    private int[] guidesValues;    private float height;    private float width;    private Paint linkLinePoint;    private Paint shadePoint;    private Paint xTextPoint;    private Paint xLintPoint;    private Paint yTextPoint;    private float itemHeight;    //ATTR    private int attrXTextColor;    private float attrXTextSize;    private int attrXLineColor;    private float attrXLineWidth;    private int attrYTextColor;    private float attrYTextSize;    private float attrLineWidth;    private int attrLinkLineColor;    private int attrShadeColor;    private float attrGuidesTextMarginLeft;    private float attrGuidesTextMarginRight;    private float attrPaddingRight;    private int maxValue; // 最大值    private float itemWidth;    private float contentEndY;    private float contentStartX;    public HeartRateView(Context context) {        super(context);    }    public HeartRateView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init(context, attrs);    }    public HeartRateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs);    }    public HeartRateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        init(context, attrs);    }    private void init(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HeartRateView);        attrLineWidth = typedArray.getDimension(R.styleable.HeartRateView_hr_lineWidth, dip2px(0.5f));        attrLinkLineColor = typedArray.getColor(R.styleable.HeartRateView_hr_linkLineColor, Color.RED);        attrShadeColor = typedArray.getColor(R.styleable.HeartRateView_hr_shadeColor, Color.RED);        maxValue = typedArray.getInteger(R.styleable.HeartRateView_hr_maxValue, 180);        attrXTextColor = typedArray.getColor(R.styleable.HeartRateView_hr_xTextColor, Color.GRAY);        attrXTextSize = typedArray.getDimension(R.styleable.HeartRateView_hr_xTextSize, 20);        attrXLineColor = typedArray.getColor(R.styleable.HeartRateView_hr_xLineColor, Color.GRAY);        attrYTextSize = typedArray.getDimension(R.styleable.HeartRateView_hr_yTextSize, 20);        attrYTextColor = typedArray.getColor(R.styleable.HeartRateView_hr_yTextColor, Color.GRAY);        attrXLineWidth = typedArray.getDimension(R.styleable.HeartRateView_hr_xLineWidth, dip2px(0.5f));        attrGuidesTextMarginLeft = typedArray.getDimension(R.styleable.HeartRateView_hr_guidesTextMarginLeft, 20);        attrGuidesTextMarginRight = typedArray.getDimension(R.styleable.HeartRateView_hr_guidesTextMarginRight, 20);        attrPaddingRight = typedArray.getDimension(R.styleable.HeartRateView_hr_paddingRight, 20);        typedArray.recycle();        linkLinePoint = new Paint();        linkLinePoint.setColor(attrLinkLineColor);        linkLinePoint.setStrokeWidth(attrLineWidth);        linkLinePoint.setStyle(Paint.Style.STROKE);        linkLinePoint.setAntiAlias(true);        shadePoint = new Paint();        shadePoint.setStyle(Paint.Style.FILL);        xTextPoint = new Paint();        xTextPoint.setColor(attrXTextColor);        xTextPoint.setTextSize(attrXTextSize);        xTextPoint.setAntiAlias(true);        yTextPoint = new Paint();        yTextPoint.setColor(attrYTextColor);        yTextPoint.setTextSize(attrYTextSize);        yTextPoint.setAntiAlias(true);        xLintPoint = new Paint();        xLintPoint.setColor(attrXLineColor);        xLintPoint.setStrokeWidth(attrXLineWidth);        xLintPoint.setAntiAlias(true);        xLintPoint.setStyle(Paint.Style.STROKE);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = getMeasuredWidth();        height = getMeasuredHeight();        contentEndY = height - measureTextHeight(xTextPoint);        itemHeight = contentEndY / maxValue;        contentStartX = attrGuidesTextMarginLeft + yTextPoint.measureText(String.valueOf(maxValue)) + attrGuidesTextMarginRight;    }    public static float measureTextHeight(Paint paint) {        float height = 0f;        if (null == paint) {            return height;        }        Paint.FontMetrics fontMetrics = paint.getFontMetrics();        height = fontMetrics.descent - fontMetrics.ascent;        return height;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (guidesValues != null && guidesValues.length > 0) {            for (int guidesValue : guidesValues) {                float x = attrGuidesTextMarginLeft;                float y = contentEndY - guidesValue * itemHeight;                canvas.drawText(String.valueOf(guidesValue), x, y, yTextPoint);            }        }        if (values != null && values.size() > 1) {            Path path = new Path();            Path pathLine = new Path();            path.moveTo(contentStartX, contentEndY - values.get(0) * itemHeight);            pathLine.moveTo(contentStartX, contentEndY - values.get(0) * itemHeight);            for (int i = 1; i < values.size(); i++) {                float x = contentStartX + i * itemWidth;                float y = contentEndY - values.get(i) * itemHeight;                // 为了美观,计算误差在最后一个点消除                if (i == values.size() - 1) {                    x = width - attrPaddingRight;                }                path.lineTo(x, y);                pathLine.lineTo(x, y);            }            path.lineTo(width - attrPaddingRight, contentEndY);            path.lineTo(contentStartX, contentEndY);            path.lineTo(contentStartX, contentEndY - values.get(0) * itemHeight);            path.close();            Shader mShader = new LinearGradient(0, contentEndY, 0, 0, Color.WHITE, attrShadeColor, Shader.TileMode.MIRROR);            shadePoint.setShader(mShader);            canvas.drawPath(path, shadePoint);            canvas.drawPath(pathLine, linkLinePoint);        }        // X 轴        canvas.drawLine(0, contentEndY, width, contentEndY, xLintPoint);    }    public void setValues(List values) {        this.values = values;        itemWidth = (width - attrPaddingRight - contentStartX) / values.size();        postInvalidate();    }    /**     * 设置参考值     *     * @param values     */    public void setGuidesValues(int[] values) {        this.guidesValues = values;    }    private float dip2px(float dpValue) {        final float scale = getContext().getResources().getDisplayMetrics().density;        return (dpValue * scale + 0.5f);    }}

attrs.xml添加属性

                                                    

更多相关文章

  1. Android之——模拟实现检测心率变化的应用实例
  2. android 默认系统音量定义
  3. layout中设置图片自适应大小,并且设置最大宽高
  4. Android(安卓)ProgressBar的使用
  5. ProgressBar用法
  6. Android技能树 — 排序算法基础小结
  7. 模拟数组pop,push,toString和冒泡排序(sort的使用)
  8. js 实现数组排序 获取最大值,最小值,翻转
  9. 做了一个 62 进制的简单实现

随机推荐

  1. Crypto.js:在IE 11中未定义“Uint8Clamped
  2. 使用自动化测试框架selenium,批量的进行截
  3. 如何将对象作为参数传播给函数?
  4. [生活娱乐] 从后端室友那学来的代码
  5. 来自jQuery的Javascript中的等效函数
  6. 推荐几款制作网页滚动动画的 JavaScript
  7. Javascript语法中null与“”的误写导致长
  8. ng- repeat显示的行等于no属性,甚至不显示
  9. 获取下一个DOM元素的ID
  10. 使用Directive通过AngularJS使用指令和数