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(汽车速度仪,刻度盘等),多种自定义模式,满足多种需求

效果图源码点我点我,欢迎star or fork
  • u013724061
  • u013724061
  • 2015年11月05日 11:24
  • 3565

自定义View实战(一) 汽车速度仪表盘

自定义View实战(一) 汽车速度仪表盘  转载请以链接形式标明出处:  http://blog.csdn.net/lxk_1993/article/details/5137326...
  • lxk_1993
  • lxk_1993
  • 2016年05月11日 13:02
  • 9074

android 仿汽车仪表盘

android 仿汽车仪表盘
  • coderinchina
  • coderinchina
  • 2016年08月28日 20:04
  • 2060

仪表图的实现--Android

由于项目中有数据需要通过仪表图进行数据的展示,所以在此进行一下总结,数据仪表图的实现方法本人用过的有3种,分别进行一下总结。 1.通过加载webview来显示仪表图   这种方式类似于使用网页的形...
  • max1198
  • max1198
  • 2015年07月19日 22:49
  • 1437

Android仪表盘

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

Android 自定义仪表盘

最近需要写一个用到各种图表的项目,比较过后决定用hellocharts框架,感觉足够简洁,后来发现这框架里没有仪表盘这个控件,但又不想换其他框架,于是在网上搜索一番,找到一个仪表盘学习demo,尝试后...
  • u011144425
  • u011144425
  • 2017年07月04日 10:08
  • 397

Android的一款自定义的仪表盘控件

  • 2015年07月29日 21:14
  • 2.21MB
  • 下载

Android 仪表盘View

Android仪表板 可以用手指改变运动轨迹
  • qq_26411333
  • qq_26411333
  • 2016年09月02日 20:53
  • 2895

android 自定义view实现表盘效果

android 自定义view实现表盘效果
  • coderinchina
  • coderinchina
  • 2016年11月06日 22:00
  • 2869

Android 自定义View 实现表盘效果

看一哥们做了这个效果,我也来凑下热闹 我的实现: package com.stone.clock.view; import android.content.Context; impor...
  • jjwwmlp456
  • jjwwmlp456
  • 2016年11月07日 20:36
  • 1806
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 仿汽车仪表盘
举报原因:
原因补充:

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