01.自定义View(ArcView弧形进度条)

简介: 开始重新学习一下自定义View的相关知识,借鉴了一些网上的文章,目前在跟这位博主学习,大家可以关注一下作者:红橙Darren链接:https://www.

开始重新学习一下自定义View的相关知识,借鉴了一些网上的文章,目前在跟这位博主学习,大家可以关注一下

作者:红橙Darren
链接:https://www.jianshu.com/p/0a32e81c3c89
來源:简书

ArcView

实现效果


img_5cf440881d689d43f1656a2b0ca401ce.png
QQ截图20180323075921.png
package com.example.mylibrary.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.example.mylibrary.R;

/**
 * Created by renzhenming on 2018/3/22.
 * 圆弧形的进度条
 */

public class ArcView extends View{

    private final Paint mBackgroundPaint;
    private final Paint mForegroundPaint;
    private final Paint mTextPaint;

    //中间字体颜色
    private int mCenterTextColor = Color.RED;

    //中间字体大小
    private int mCenterTextSize = 40;

    //进度条宽度
    private float mBorderWidth = 20;

    //进度条已完成部分颜色
    private int mForegroundColor = Color.RED;

    //进度条进行中部分颜色
    private int mBackgroundColor = Color.BLUE;

    //总量和当前量
    private float mTotalPercent = 0f;
    private float mCurrentPercent = 0f;

    public ArcView(Context context) {
        this(context,null);
    }

    public ArcView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,-1);
    }

    public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcView);
        mBackgroundColor = typedArray.getColor(R.styleable.ArcView_backgroundColor, mBackgroundColor);
        mForegroundColor = typedArray.getColor(R.styleable.ArcView_foregroundColor, mForegroundColor);
        mBorderWidth = typedArray.getDimension(R.styleable.ArcView_borderWidth,mBorderWidth);
        mCenterTextSize = typedArray.getDimensionPixelSize(R.styleable.ArcView_centerTextSize,mCenterTextSize);
        mCenterTextColor = typedArray.getColor(R.styleable.ArcView_centerTextColor,mCenterTextColor);
        typedArray.recycle();

        mBackgroundPaint = new Paint();
        mBackgroundPaint.setAntiAlias(true);
        mBackgroundPaint.setStrokeWidth(mBorderWidth);
        mBackgroundPaint.setColor(mBackgroundColor);
        //STROKE 画出来的圆弧不是封闭的,FILL是封闭的
        mBackgroundPaint.setStyle(Paint.Style.STROKE);
        mBackgroundPaint.setDither(true);
        //Paint.Cap.ROUND设置圆弧首尾位置是ROUND的,不是直角
        //Paint.Cap.SQUARE默认的是直角
        mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND);

        mForegroundPaint = new Paint();
        mForegroundPaint.setAntiAlias(true);
        mForegroundPaint.setStrokeWidth(mBorderWidth);
        mForegroundPaint.setDither(true);
        mForegroundPaint.setColor(mForegroundColor);
        //STROKE 画出来的圆弧不是封闭的,FILL是封闭的
        mForegroundPaint.setStyle(Paint.Style.STROKE);
        //Paint.Cap.ROUND设置圆弧首尾位置是ROUND的,不是直角
        //Paint.Cap.SQUARE默认的是直角
        mForegroundPaint.setStrokeCap(Paint.Cap.ROUND);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setDither(true);
        mTextPaint.setColor(mCenterTextColor);
        mTextPaint.setTextSize(mCenterTextSize);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //如果宽度和高度不一样,取最小值,确保是个正方形
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width>height?height:width,width>height?height:width);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画背景,
        RectF rectF = new RectF(mBorderWidth / 2, mBorderWidth / 2, getWidth() - mBorderWidth / 2, getHeight() - mBorderWidth / 2);
        //false表示圆弧不闭合,绘制的宽度也要占空间,所以RectF的设置上下左右要考虑去掉宽度的一般,猜测,
        //绘制的时候是从边缘宽度的中心开始计算的
        canvas.drawArc(rectF, 135, 270, false, mBackgroundPaint);

        //画进行中的进度
        if (mTotalPercent ==0 )return;
        if ( mCurrentPercent > mTotalPercent){
            mCurrentPercent = mTotalPercent;
        }
        float sweepAngle = mCurrentPercent/mTotalPercent;
        canvas.drawArc(rectF,135,sweepAngle*270,false,mForegroundPaint);

        //画文字
        String s = ((int)mCurrentPercent) + "";
        Rect bounds = new Rect();
        mTextPaint.getTextBounds(s,0,s.length(),bounds);

        //获取文字的起始位置,文字位于控件中间,所以起始位置等于控件宽度的
        //一半减去文字宽度的一半
        int start = getWidth()/2-bounds.width()/2;


        Paint.FontMetrics metrics = mTextPaint.getFontMetrics();

        //文字高度
        //文字中心点距离底部的距离
        int dy = (int) ((metrics.bottom-metrics.top)/2-metrics.bottom);

        //获取基线baseline
        int baseLine = getHeight()/2+dy;
        canvas.drawText(s,start,baseLine,mTextPaint);
    }

    /**
     * 设置总量
     * @param totalProgress
     */
    public synchronized void setTotalProgress(int totalProgress){
        this.mTotalPercent = totalProgress;
    }

    /**
     * 设置当前量
     * @param currentProgress
     */
    public synchronized void setCurrentProgress(int currentProgress){
        this.mCurrentPercent = currentProgress;
        invalidate();
    }
}

attrs

<!--半圆弧进度条-->
    <declare-styleable name="ArcView">
        <attr name="backgroundColor" format="color"/>
        <attr name="foregroundColor" format="color"/>
        <attr name="borderWidth" format="dimension"/>
        <attr name="centerTextSize" format="dimension"/>
        <attr name="centerTextColor" format="color"/>
    </declare-styleable>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.app.rzm.test.TextCustomeViewActivity">
    <com.example.mylibrary.view.ArcView
        android:id="@+id/arcView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

测试

public class TextCustomeViewActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_custormer_view);
        final ArcView mArcView = (ArcView) findViewById(R.id.arcView);
        mArcView.setTotalProgress(1000);
        ValueAnimator animator = ValueAnimator.ofFloat(0,2000);
        animator.setDuration(2000);
        animator.start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float currentProgress = (float) animation.getAnimatedValue();
                mArcView.setCurrentProgress((int) currentProgress);
            }
        });
    }
}
相关文章
|
6月前
|
XML API Android开发
Android 自定义View 之 圆环进度条
Android 自定义View 之 圆环进度条
114 0
|
Android开发
Android自定义View 水波气泡2
Android自定义View 水波气泡
|
11月前
水波纹按钮动画
水波纹按钮动画
46 0
水波纹按钮动画
|
Android开发
Android自定义View 水波气泡1
Android自定义View 水波气泡
Android自定义View 水波气泡1
|
XML Java API
一个超简单的渐变平行四边形进度条
这个自定义View,其实就是一个简单的进度条,无非就是平行四边形形状的,加了渐变以及状态颜色的切换。
133 0
|
Android开发 内存技术
Android动画(帧动画、补间动画、属性动画)讲解
帧动画:是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。 补间动画:指的是做FLASH动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动; 属性动画:帧动画与补间动画实现了对View进行移动、缩放、旋转和淡入淡出的效果。但对于android开发师来说是不够的,同时移动、缩放、旋转和淡入淡出的效果也不再只是一种视觉上的动画效果了。所以从Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation)。
344 0
Android动画(帧动画、补间动画、属性动画)讲解
|
XML 前端开发 Android开发
Android 渐变圆环,圆形进度条效果实现
Android 渐变圆环,圆形进度条效果实现
Android 渐变圆环,圆形进度条效果实现
粒子效果进度条
在线演示 本地下载
1307 0
|
前端开发 Android开发 Rust
Android - 条纹进度条实现,调整view宽度仿进度条
相关代码请参阅: https://github.com/RustFisher/aboutView/blob/master/app/src/main/java/com/rust/aboutview/activity/RoundCornerActivity.java 美工同学指定了一个进度条样式 这斑斓的进度条,如果要自己画实在是劳民伤财。
3240 0
|
前端开发 Java Android开发
自定义View——画板
今天实现的是画板效果 image 实现原理 image 根据触摸事件返回的坐标点绘制path路径 @Override public boolean onTouchEvent(MotionEvent event) { x = event.
1014 0