Android 自定义的圆形变化ProgressBar
来源:互联网 发布:淘宝海报图片 编辑:程序博客网 时间:2024/04/27 13:54
Android 自带的ProgressBar中大多比较丑,所以自己定制了一个ProgressBar,可以实现动态的播放,先看截图
然后上代码,^_^原谅我不会说别的。
先看主程序布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="@color/simple_bg" tools:context=".MainActivity" > <lib.vgod.progresscicle.library.DashProgressBar android:id="@+id/simple" custom:external_color="#1affffff" custom:base_color="#6effffff" custom:min="0" custom:max="999" custom:progress_color="#000000" custom:progress_icon="@drawable/star" custom:duration="1500" android:layout_centerInParent="true" android:layout_width="300dp" android:layout_height="300dp"> <RelativeLayout android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:textSize="25sp" android:id="@+id/text" android:textColor="#000000" android:text="@string/stars" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:textSize="30sp" android:layout_centerHorizontal="true" android:id="@+id/number" android:paddingTop="5dp" android:layout_below="@+id/text" android:textColor="#000000" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> </lib.vgod.progresscicle.library.DashProgressBar> <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/simple" android:layout_alignParentLeft="true" android:text="@string/start"/> <Button android:id="@+id/restart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/simple" android:layout_toRightOf="@id/start" android:text="@string/restart"/></RelativeLayout>然后主程序
package lib.vgod.progresscicle;import lib.vgod.progresscicle.library.DashProgressBar;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {DashProgressBar dashProgressBar;Button startBtn;Button restartBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dashProgressBar = (DashProgressBar)findViewById(R.id.simple); startBtn = (Button)findViewById(R.id.start); restartBtn = (Button)findViewById(R.id.restart); startBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {dashProgressBar.startAnimate();}}); restartBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {dashProgressBar.restartAnimate();}}); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
这里我自定义了一个绘制板,包括draw(),onSizeChanged()主要是方便在View中draw方法和onSizeChanged调用
package lib.vgod.progresscicle.library;import android.graphics.Canvas;/** * @author niuwei * */public interface Painter {void draw(Canvas canvas);void onSizeChanged(int width, int height);void setColor(int color);int getColor();}然后是绘制外部圆圈的绘制板
package lib.vgod.progresscicle.library;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;public class ExternalCirclePainter implements Painter{private Paint externalPainter;private RectF externalCircle;private int color;//颜色 private int externalStrokeWidth = 4;//椭圆宽度 private int startAngle = 279;//开始角度 private int finishAngle = 341;//结束角度 private int width;//宽 private int height;//高 private float marginTop = 11;//上边距 /** * 初始构造器,构造外部圆圈画笔的颜色 * @param externalColor */ public ExternalCirclePainter(int externalColor) { this.color = externalColor; init(); } /** * 初始化 */ private void init() { initExternalCirclePainter(); } /** * 初始化画笔 */ private void initExternalCirclePainter() { externalPainter = new Paint(); externalPainter.setAntiAlias(true); externalPainter.setStrokeWidth(externalStrokeWidth); externalPainter.setColor(color); externalPainter.setStyle(Paint.Style.STROKE); } /** * 初始化圆圈的大小 */ private void initExternalCircle() { externalCircle = new RectF(); externalCircle.set(externalStrokeWidth, externalStrokeWidth * marginTop, width - externalStrokeWidth, height - externalStrokeWidth); } @Overridepublic void draw(Canvas canvas) {canvas.drawArc(externalCircle, startAngle, finishAngle, false, externalPainter);}@Overridepublic void onSizeChanged(int width, int height) {this.width = width;this.height = height;initExternalCircle();}@Overridepublic void setColor(int color) {this.color = color;}@Overridepublic int getColor() {return color;}}
绘制内部dash圆圈的绘制板,其实主要起作用的是
<span style="color:#ff0000;">internalCirclePaint.setPathEffect(new DashPathEffect(new float[]{dashWidth, dashSpace}, dashSpace));</span>
package lib.vgod.progresscicle.library;import android.graphics.Canvas;import android.graphics.DashPathEffect;import android.graphics.Paint;import android.graphics.RectF;public class InternalCirclePainter implements Painter{private RectF internalCircle; private Paint internalCirclePaint; private int color; private float startAngle = 270; private float finishAngle = 359.8f; private int width; private int height; private int internalStrokeWidth = 48; private int dashWidth = 5; private int dashSpace = 8; private float marginTop = 45; /** * 初始构造器,构造外部圆圈画笔的颜色 * @param externalColor */ public InternalCirclePainter(int externalColor) { this.color = externalColor; init(); } /** * 初始化 */ private void init() { initInternalCirclePainter(); } /** * 初始化绘制圆圈的画笔 */ private void initInternalCirclePainter(){ internalCirclePaint = new Paint(); internalCirclePaint.setAntiAlias(true); internalCirclePaint.setStrokeWidth(internalStrokeWidth); internalCirclePaint.setColor(color); internalCirclePaint.setStyle(Paint.Style.STROKE); internalCirclePaint.setPathEffect(new DashPathEffect(new float[]{dashWidth, dashSpace}, dashSpace)); } /** * 初始化内部圆圈的大小 */ private void initInternalCircle(){ internalCircle = new RectF(); float padding = internalStrokeWidth * 1.7f; internalCircle.set(padding, padding + marginTop, width - padding, height - padding); } @Overridepublic void draw(Canvas canvas) {canvas.drawArc(internalCircle, startAngle, finishAngle, false, internalCirclePaint);}@Overridepublic void onSizeChanged(int width, int height) {this.width = width; this.height = height; initInternalCircle();}@Overridepublic void setColor(int color) {this.color = color;internalCirclePaint.setColor(this.color);}@Overridepublic int getColor() {return this.color;}}
然后是可变化的dash圆圈的接口
package lib.vgod.progresscicle.library;/** * @author niuwei * */public interface ProgressPainter extends Painter{void setMax(float max); void setMin(float min); void setValue(float value);}
可变化的绘制圆圈类
package lib.vgod.progresscicle.library;import android.graphics.Canvas;import android.graphics.DashPathEffect;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.RectF;/** * @author niuwei * */public class ProgressPainterImp implements ProgressPainter{private float min;private float max;private int mColor;private Paint mPaint;private RectF progressCircle;private float startAngle = 270f; private float plusAngle = 0;private int width; private int height; private int internalStrokeWidth = 48; private int dashWidth = 5; private int dashSpace = 8; private float marginTop = 45; private float padding; public ProgressPainterImp(int color, float min, float max){ mColor = color; this.min = min; this.max = max; init(); } private void init(){ initInternalCirclePainter(); } private void initInternalCirclePainter() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(mColor); mPaint.setStrokeWidth(internalStrokeWidth); mPaint.setStyle(Style.STROKE); mPaint.setPathEffect(new DashPathEffect(new float[]{dashWidth, dashSpace}, dashSpace)); } private void initInternalCircle() { progressCircle = new RectF(); padding = internalStrokeWidth * 1.7f; progressCircle.set(padding, padding + marginTop, width - padding, height - padding); } @Overridepublic void draw(Canvas canvas) {canvas.drawArc(progressCircle, startAngle, plusAngle, false, mPaint);}@Overridepublic void onSizeChanged(int width, int height) {this.width = width;this.height = height;initInternalCircle();}@Overridepublic void setColor(int color) {this.mColor = color;mPaint.setColor(this.mColor);}@Overridepublic int getColor() {return mColor;}@Overridepublic void setMax(float max) {this.max = max;}public float getMax(){return max;}@Overridepublic void setMin(float min) {this.min = min;}public float getMin(){return min;}@Overridepublic void setValue(float value) {plusAngle = (359.8f * value) / max;}}
绘制中心图片
package lib.vgod.progresscicle.library;import android.graphics.Canvas;import android.graphics.DashPathEffect;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.RectF;/** * @author niuwei * */public class ProgressPainterImp implements ProgressPainter{private float min;private float max;private int mColor;private Paint mPaint;private RectF progressCircle;private float startAngle = 270f; private float plusAngle = 0;private int width; private int height; private int internalStrokeWidth = 48; private int dashWidth = 5; private int dashSpace = 8; private float marginTop = 45; private float padding; public ProgressPainterImp(int color, float min, float max){ mColor = color; this.min = min; this.max = max; init(); } private void init(){ initInternalCirclePainter(); } private void initInternalCirclePainter() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(mColor); mPaint.setStrokeWidth(internalStrokeWidth); mPaint.setStyle(Style.STROKE); mPaint.setPathEffect(new DashPathEffect(new float[]{dashWidth, dashSpace}, dashSpace)); } private void initInternalCircle() { progressCircle = new RectF(); padding = internalStrokeWidth * 1.7f; progressCircle.set(padding, padding + marginTop, width - padding, height - padding); } @Overridepublic void draw(Canvas canvas) {canvas.drawArc(progressCircle, startAngle, plusAngle, false, mPaint);}@Overridepublic void onSizeChanged(int width, int height) {this.width = width;this.height = height;initInternalCircle();}@Overridepublic void setColor(int color) {this.mColor = color;mPaint.setColor(this.mColor);}@Overridepublic int getColor() {return mColor;}@Overridepublic void setMax(float max) {this.max = max;}public float getMax(){return max;}@Overridepublic void setMin(float min) {this.min = min;}public float getMin(){return min;}@Overridepublic void setValue(float value) {plusAngle = (359.8f * value) / max;}}
继承自RelativeLayout的类
package lib.vgod.progresscicle.library;import lib.vgod.progresscicle.R;import android.animation.ValueAnimator;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.view.animation.AccelerateDecelerateInterpolator;import android.widget.RelativeLayout;/** * @author niuwei * */@SuppressLint("NewApi") public class DashProgressBar extends RelativeLayout{private final static String TAG = "DashProgressBar";/** * 内圈的颜色 */private int externalCircleColor = Color.GRAY;/** * 外圈的颜色 */private int internalCircleColor = Color.YELLOW;/** * Progress的颜色 */private int progressCircleColor = Color.WHITE;/** * Progress的最大值 */private float progressMax;/** * Progress的最小值 */private float progressMin = 0;/** * Progress的当前值 */private float progressLast = progressMin;/** * 需要显示的图标 */private Bitmap iconBitmap;/** * 动画持续时间 */private int ANIMATION_DURATION = 1000;/** * 动画加速器 */private AccelerateDecelerateInterpolator mInterpolator;/** * 动画 */private ValueAnimator mValueAnimator;/** * 外部执行操作的接口 */private OnValueChangeListener mOnValueChangeListener;/** * 画笔元素 */private ExternalCirclePainter externalCirclePainter;private InternalCirclePainter internalCirclePainter;private BitmapPainter bitmapPainter;private ProgressPainterImp progressPainterImp;private int heightNormalittation = 10;public DashProgressBar(Context context, AttributeSet attrs) {super(context, attrs);init(context, attrs);}public DashProgressBar(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);init(context, attrs);}/** * 初始化函数 */private void init(Context context, AttributeSet attributeSet){setWillNotDraw(false);initAttributes(attributeSet);initPainter();initData();}/** * 初始化变量 */private void initData(){mInterpolator = new AccelerateDecelerateInterpolator();initAnimate();}/** * 初始化动画 */private void initAnimate(){mValueAnimator = new ValueAnimator();mValueAnimator.setInterpolator(mInterpolator);mValueAnimator.addUpdateListener(new ValueAnimationChangeListener());}/** * 初始化属性 */private void initAttributes(AttributeSet attributeSet){TypedArray ta = getContext().obtainStyledAttributes(attributeSet, R.styleable.DashedCircleProgress);externalCircleColor = ta.getColor(R.styleable.DashedCircleProgress_external_color, externalCircleColor);internalCircleColor = ta.getColor(R.styleable.DashedCircleProgress_base_color, internalCircleColor);progressCircleColor = ta.getColor(R.styleable.DashedCircleProgress_progress_color, progressCircleColor);progressMax = ta.getFloat(R.styleable.DashedCircleProgress_max, progressMax);ANIMATION_DURATION = ta.getInt(R.styleable.DashedCircleProgress_duration, ANIMATION_DURATION);iconBitmap = BitmapFactory.decodeResource(getResources(), ta.getResourceId(R.styleable.DashedCircleProgress_progress_icon, 0));ta.recycle();}/** * 初始化画笔 */private void initPainter(){internalCirclePainter = new InternalCirclePainter(internalCircleColor);externalCirclePainter = new ExternalCirclePainter(externalCircleColor);bitmapPainter = new BitmapPainter(iconBitmap);progressPainterImp = new ProgressPainterImp(progressCircleColor, progressMin, progressMax);}/** * 开始动画 */public void startAnimate(float max){if (mValueAnimator != null) {mValueAnimator.setFloatValues(progressLast, max);mValueAnimator.setDuration(ANIMATION_DURATION);mValueAnimator.start();}}/** * 开始动画 */public void startAnimate(){if (mValueAnimator != null) {mValueAnimator.setFloatValues(progressLast, progressMax);mValueAnimator.setDuration(ANIMATION_DURATION);mValueAnimator.start();}}/** * 重新开始动画 */public void restartAnimate(){progressLast = progressMin;startAnimate(progressMax);}/** * 设置动画执行到什么时候 */public void setValue(int value){if (value <= progressMax && value >= progressMin) {progressLast = progressMin;startAnimate(value);}}/** * 动画监听器,更新内部绘制画面和外部接口回调 * @author niuwei * */private class ValueAnimationChangeListener implements ValueAnimator.AnimatorUpdateListener {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {Float value = (Float)valueAnimator.getAnimatedValue();progressPainterImp.setValue(value);if (mOnValueChangeListener != null) {mOnValueChangeListener.onChange(value);}progressLast = value;}}/** * 接口,当动画改编的过程中UI线程可以进行一些操作 */private interface OnValueChangeListener{void onChange(float change);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);Log.d(TAG, "onLayout()");final int count = getChildCount();int maxWidth = getWidth() / 2;int maxHeight = getHeight() / 2;for (int i = 0; i < count; i++) {final View child = getChildAt(i);int mesaureWidth = child.getMeasuredWidth();int measureHeight = child.getMeasuredHeight();ViewGroup.LayoutParams layoutParams = child.getLayoutParams();RelativeLayout.LayoutParams relativeLayoutParams = (RelativeLayout.LayoutParams) child.getLayoutParams(); relativeLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); child.setLayoutParams(relativeLayoutParams);if (mesaureWidth > maxWidth) { layoutParams.width = maxWidth; } if (measureHeight > maxHeight) { layoutParams.height = maxHeight; }}}@Overrideprotected void onDraw(Canvas canvas){super.onDraw(canvas);Log.d(TAG, "onDraw()");externalCirclePainter.draw(canvas);internalCirclePainter.draw(canvas);bitmapPainter.draw(canvas);progressPainterImp.draw(canvas);invalidate();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec + heightNormalittation);Log.d(TAG, "onMeasure()");}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);Log.d(TAG, "onSizeChanged()");externalCirclePainter.onSizeChanged(w, h);internalCirclePainter.onSizeChanged(w, h);bitmapPainter.onSizeChanged(w, h);progressPainterImp.onSizeChanged(w, h);}public void setmOnValueChangeListener(OnValueChangeListener mOnValueChangeListener) {this.mOnValueChangeListener = mOnValueChangeListener;}}
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="DashedCircleProgress"> <attr name="external_color" format="color" /> <attr name="base_color" format="color" /> <attr name="progress_color" format="color" /> <attr name="max" format="float" /> <attr name="min" format="float" /> <attr name="progress_icon" format="reference" /> <attr name="duration" format="integer" /> </declare-styleable></resources>
大功告成,需要资源可以点击下载 下载
2 0
- Android 自定义的圆形变化ProgressBar
- Android自定义圆形ProgressBar
- Android 自定义圆形progressbar
- android 自定义圆形ProgressBar
- Android自定义水平和圆形的progressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- 自定义圆形的ProgressBar
- android开发 自定义圆形Progressbar
- android获取手机内部存储空间和外部存储空间
- ibatis中使用like模糊查询
- UNITY3D 使用 litjson 制作数据表
- Reduce对Pig作业性能的影响
- android动画坐标定义
- Android 自定义的圆形变化ProgressBar
- [转]一个手机游戏的服务器架构
- 学习C指针的心得随笔
- Leetcode:Palindrome Partitioning
- error和exception的区别,RuntimeException和非RuntimeException的区别
- RT-Thread 学习笔记(十一)--- 开启基于RTGUI的LCD显示功能(1)<LCD驱动接口移植>
- python学习笔记3
- 内连接,外连接,左连接,右连接,全连接,内连接,交叉连接,自连接
- Chrome渲染Transition时页面闪动Bug