android 仿汽车仪表盘

原创 2016年08月28日 20:04:57

这个就是使用Paint和Canvas一个个画上去的,再加上动画,总体来说不难,就是变量多,所以看起来的时候要慢慢看,现在在这贴下代码

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <SeekBar
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10px"
        android:paddingRight="10px"
        android:layout_marginTop="20px"
        />
    <LinearLayout
        android:layout_width="300px"
        android:layout_height="300px"
        android:layout_marginTop="90px"
        android:layout_marginLeft="60px"
        >
    <com.example.speeddemo.CarRecorderView
        android:id="@+id/carview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#8B5F65"
         />
    </LinearLayout>
</RelativeLayout>

自定义veiw

package com.example.speeddemo;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/8/28.
 */
public class CarRecorderView extends View {
    private static final String TAG = "CarRecorderView" ;
    private LinearGradient linearGradient = null;
    private Paint blackCirclePaint;
    private int blackCirClePaintWidth = 8;

    private Paint arcAnimPaint;
    private Paint outerAnimPaint;
    private Paint whiteCirclePaint ;
    private Paint unitTextPaint;
    private int whiteCirclePaintWidth = 24;
    private Paint outerPaint;
    private Paint linePaint;
    private Paint textValuePaint;
    private Paint interprogressPaint;

    private int lineWidth = 5;
    private Paint outerSmallPaint;
    private RectF outerRectF;
    private RectF outerAnimRectF ;
    private Bitmap carBitmap;

    private int width;
    private int height;

    private int min = 0;
    private float value;
    private long duration = 1000;
    private long progressDelay = 350;
    private int startAngle = 140;//开始的角度
    private float plusAngle = 0;//经过的角度
    private float maxAngle = 260f;//最大的角度
    private float outerProgressValue = min;
    private float lineInitValue = min;
    private int max = 100;//最大进度值
    private ValueAnimator lineAnim;
    private ValueAnimator outerProgressAnim;
    public CarRecorderView(Context context) {
        super(context);
    }

    public CarRecorderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
        initAnim();
    }

    private void updateOuterProgressValue(float value) {
        setOuterAnimAngle(value);
    }

    public void setOuterAnimAngle(float value){
        this.plusAngle = (maxAngle * value) / max;
        invalidate();
    }
    private void updateProgressText(float value) {
        updateValue(value);
    }
    /**
     * 初始化画笔
     */
    private void initPaint() {
        arcAnimPaint = new Paint();
        arcAnimPaint.setStrokeWidth(12);
        arcAnimPaint.setColor(Color.parseColor("#1C86EE"));
        arcAnimPaint.setAntiAlias(true);
        arcAnimPaint.setStyle(Paint.Style.STROKE);

        interprogressPaint = new Paint();
        interprogressPaint.setStrokeWidth(12);
        interprogressPaint.setColor(Color.RED);
        interprogressPaint.setAntiAlias(true);
        interprogressPaint.setStyle(Paint.Style.STROKE);

        unitTextPaint = new Paint();
        unitTextPaint.setColor(Color.parseColor("#DBDBDB"));
        unitTextPaint.setTextSize(20);
        unitTextPaint.setAntiAlias(true);

        textValuePaint = new Paint();
        textValuePaint.setColor(Color.parseColor("#DBDBDB"));
        textValuePaint.setTextSize(40);
        textValuePaint.setAntiAlias(true);

        blackCirclePaint = new Paint();
        blackCirclePaint.setColor(Color.parseColor("#1A1A1A"));
        blackCirclePaint.setStrokeWidth(blackCirClePaintWidth);
        blackCirclePaint.setStyle(Paint.Style.STROKE);
        blackCirclePaint.setAntiAlias(true);

        whiteCirclePaint = new Paint();
        whiteCirclePaint.setColor(Color.parseColor("#1A1A1A"));
        whiteCirclePaint.setStrokeWidth(whiteCirclePaintWidth);
        whiteCirclePaint.setStyle(Paint.Style.STROKE);
        whiteCirclePaint.setAntiAlias(true);

        outerPaint = new Paint();
        outerPaint.setColor(Color.parseColor("#080808"));
        outerPaint.setStrokeWidth(whiteCirclePaintWidth);
        outerPaint.setStyle(Paint.Style.STROKE);
        outerPaint.setAntiAlias(true);


        outerSmallPaint = new Paint();
        outerSmallPaint.setColor(Color.RED);
        outerSmallPaint.setStrokeWidth(whiteCirclePaintWidth-8);
        outerSmallPaint.setStyle(Paint.Style.STROKE);
        outerSmallPaint.setAntiAlias(true);

        linePaint = new Paint();
        linePaint.setColor(Color.parseColor("#20B2AA"));
        linePaint.setStrokeWidth(lineWidth);
        linePaint.setStyle(Paint.Style.FILL);
        linePaint.setAntiAlias(true);


        float[] intervals =new float[]{8,12};
        DashPathEffect dashPathEffect = new DashPathEffect(intervals,0);
        outerPaint.setPathEffect(dashPathEffect);


        outerAnimPaint = new Paint();
        outerAnimPaint.setColor(Color.RED);
        outerAnimPaint.setPathEffect(dashPathEffect);
        outerAnimPaint.setStyle(Paint.Style.STROKE);
        outerAnimPaint.setAntiAlias(true);
        outerAnimPaint.setStrokeWidth(whiteCirclePaintWidth);

        carBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.car1);

        linearGradient = new LinearGradient(0, 0, 50, 50, new int[] {
                Color.parseColor("#A4D3EE"),  Color.parseColor("#9400D3"), Color.parseColor("#43CD80"), Color.parseColor("#528B8B") }, null,
                Shader.TileMode.REPEAT);
        outerPaint.setShader(linearGradient);
    }
    public CarRecorderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        widthSize = heightSize > widthSize ?widthSize:heightSize;
        heightSize = heightSize > widthSize ?widthSize:heightSize;
        setMeasuredDimension(widthSize,heightSize);
        height = width = widthSize;
   }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
            canvas.drawCircle(width/2,height/2,width/2,blackCirclePaint);
            canvas.drawCircle(width/2,height/2,width/2-blackCirClePaintWidth,whiteCirclePaint);
            canvas.drawBitmap(carBitmap,(width-carBitmap.getWidth())/2,(height-carBitmap.getHeight())/2,blackCirclePaint);
           float toX = width / 2 + (float) Math.cos(Math.toRadians(plusAngle + startAngle)) * (width/2-whiteCirclePaintWidth-2);
           float toY = width / 2 + (float) Math.sin(Math.toRadians(plusAngle + startAngle)) * (width/2-whiteCirclePaintWidth-2);
           canvas.drawLine(width/2, width/2, toX, toY, linePaint);
           canvas.drawText("kmh",width/2-50+textValuePaint.measureText("100"),height-45,unitTextPaint);
           canvas.drawText(String.format("%.0f", lineInitValue),width/2-55,height-45,textValuePaint);
            outerRectF = new RectF();
            outerAnimRectF = new RectF();
            outerAnimRectF.set(blackCirClePaintWidth-1-1,blackCirClePaintWidth-1-1,width-blackCirClePaintWidth+1+1,height-blackCirClePaintWidth+1+1);
            outerRectF.set(blackCirClePaintWidth-1-1,blackCirClePaintWidth-1-1,width-blackCirClePaintWidth+1+1,height-blackCirClePaintWidth+1+1);
            canvas.drawArc(outerRectF,startAngle,maxAngle,false,outerPaint);
            canvas.drawArc(outerAnimRectF,startAngle,plusAngle,false,outerAnimPaint);

           RectF rectF = new RectF(60,60,height-60,height-60);
           canvas.drawArc(rectF,startAngle,maxAngle,false,interprogressPaint);

          canvas.drawArc(rectF,startAngle,plusAngle,false,arcAnimPaint);
    }
    public void updateValue(float value) {
        this.plusAngle = (maxAngle * value) / max;
        invalidate();
    }
    public void startAnim(float value) {
        this.value = value;
        if (value <= max && value >= min) {
            updateAnimValue();
        }
    }
    private void updateAnimValue() {
        if (lineAnim != null) {
            outerProgressAnim.setFloatValues(outerProgressValue, value);
            outerProgressAnim.setDuration(duration + progressDelay);
            outerProgressAnim.start();

            lineAnim.setFloatValues(lineInitValue, value);
            lineAnim.setDuration(duration);
            lineAnim.start();
        }
    }
    /**
     * 初始化属性动画
     */
    private void initAnim() {
        outerProgressAnim = new ValueAnimator();
        outerProgressAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float value = (Float) animation.getAnimatedValue();
                updateOuterProgressValue(value);
                outerProgressValue =  value;
            }
        });
        lineAnim = new ValueAnimator();
        lineAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float value = (Float) animation.getAnimatedValue();
                updateProgressText(value);
                lineInitValue = value;
            }
        });
    }
}

使用入口:

package com.example.speeddemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
public class MainActivity extends Activity {
    private CarRecorderView carview;
    private SeekBar seekbar;
    private int speedValue = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        seekbar = (SeekBar) findViewById(R.id.seekbar);
        carview = (CarRecorderView) findViewById(R.id.carview);
        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                carview.startAnim(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }
}
效果图:


发现这还有点bug,明天改下


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android 仪表盘View

Android仪表板 可以用手指改变运动轨迹

android自定义view之汽车仪表盘增强版

下面是改进后的效果图 原文链接: http://blog.csdn.net/lxk_1993/article/details/51373269 绘图流程总结: onLayout() 主要是...

Android仪表盘

仪表盘,看到这个我无奈了, 老大说要用这个,网上找的他说都好难看   然后自己改额,改动第三方的源码,改了挺久 最后出来了这个效果 最后看到效果  发现改的值得了 ...

Android绘图系列(三)——自定义View绘制仪表盘

这个系列主要是介绍下Android自定义View和Android绘图机制,自己能力有限,如果在介绍过程中有什么错误,欢迎指正 前言在上一篇Android绘图系列(二)——自定义View绘制基本图形中我...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Android自定义仪表盘视图

之前项目中用到了仪表盘这种视图,所以自己就画了一个,封装了起来,以便于以后使用,但是本人比较懒,好久才把博客发布出来==(愧疚)。 首先来分析一下画仪表盘的步骤,首先是画出画那个仪表盘的那个表盘,表盘...

android 自定义View 仪表盘 DashboardView 的实现

有天上班,老板突然扔给我一张图,说:这个东西能不能做一下。我说应该可以。然后老板那就没有下文了,我想既然问了,那我就抽空做一下。当我做出来的时候去找老板,我说上次你给我发的那个图,我已经做出来了,您要...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

手把手带你画一个 时尚仪表盘 Android 自定义View

拿到美工效果图,咱们程序员就得画得一模一样。 为了不被老板喷,只能多练啊。 听说你觉得前面几篇都so easy,那今天就带你做个相对比较复杂的。 今天的效果图如下(左边是ui图 右边是实现图): ...

android 仪表盘控件

github 下载地址 : github:https://github.com/zlz3371062/TestViewTurn; 1.开发原理:如图是由canvas 画成,主要用了canvas 的画...
  • gczlz
  • gczlz
  • 2016年07月23日 01:14
  • 673
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 仿汽车仪表盘
举报原因:
原因补充:

(最多只允许输入30个字)