android 仿汽车仪表盘

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

布局文件:

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


自定义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) {

            }
        });
    }
}
效果图:

android 仿汽车仪表盘_第1张图片

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


你可能感兴趣的:(自定义控件,android,动画系列)