標籤:android circlebar
計步器(Pedometer)整個項目的原始碼,感興趣的朋友可以下載來看看(記得幫小弟在github打個星~)
https://github.com/296777513/pedometer
本篇文章講的demo在這裡下載(0分下載):
http://download.csdn.net/detail/a296777513/8328461
先給幾張:
如所示,點擊中間的圓圈會依次顯示3個不同的頁面(資訊),而且圓形的進度條是動態增加的,效果還是可以的。然後給出原始碼,供大家參考
CircleBar的主要代碼
package com.example.histogram.widet;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Paint.Align;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.view.View;import android.view.animation.Animation;import android.view.animation.Transformation;/** * 這是繼承view的一個重新繪圖的圓圈的一個類 Author: liyachao email:[email protected] Date: 2015-1-5 * Time: 下午2:39 */public class CircleBar extends View {private RectF mColorWheelRectangle = new RectF();// 圓圈的矩形範圍private Paint mDefaultWheelPaint;// 繪製底部灰色圓圈的畫筆private Paint mColorWheelPaint;// 繪製藍色扇形的畫筆private Paint textPaint;// 中間文字的畫筆private Paint textPaint1;// 上下文字的畫筆private float mColorWheelRadius;// 圓圈普通狀態下的半徑private float circleStrokeWidth;// 圓圈的線條寬度private float pressExtraStrokeWidth;// 按下狀態下增加的圓圈線條增加的粗細private int mText;// 中間文字內容private int mCount;// 為了達到數字增加效果而添加的變數,他和mText其實代表一個意思private float mProgressAni;// 為了達到藍色扇形增加效果而添加的變數,他和mProgress其實代表一個意思private float mProgress;// 扇形弧度private int mTextSize;// 中間文字大小private int mTextSize1;// 上下文字大小private int mDistance;// 上下文字的距離BarAnimation anim;// 動畫類private int mType;// 根據傳入的數值判斷應該顯示的頁面public CircleBar(Context context) {super(context);init();}public CircleBar(Context context, AttributeSet attrs) {super(context, attrs);init();}public CircleBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init() {circleStrokeWidth = dip2px(getContext(), 20);// 圓圈的線條寬度pressExtraStrokeWidth = dip2px(getContext(), 2);// 按下狀態下增加的圓圈線條增加的粗細mTextSize = dip2px(getContext(), 80);// 中間文字大小mTextSize1 = dip2px(getContext(), 30);// 上下文字大小mDistance = dip2px(getContext(), 70);//文字間的距離// 繪製藍色扇形的畫筆mColorWheelPaint = new Paint();mColorWheelPaint.setAntiAlias(true);// 消除鋸齒mColorWheelPaint.setColor(0xFF29a6f6);// 設定顏色mColorWheelPaint.setStyle(Paint.Style.STROKE);// 設定空心mColorWheelPaint.setStrokeWidth(circleStrokeWidth);// 設定圓圈粗細// 繪製底部灰色圓圈的畫筆mDefaultWheelPaint = new Paint();mDefaultWheelPaint.setAntiAlias(true);mDefaultWheelPaint.setColor(Color.parseColor("#d9d6c3"));mDefaultWheelPaint.setStyle(Paint.Style.STROKE);mDefaultWheelPaint.setStrokeWidth(circleStrokeWidth);// 中間文字的畫筆textPaint = new Paint(Paint.LINEAR_TEXT_FLAG);textPaint.setAntiAlias(true);textPaint.setColor(Color.parseColor("#6DCAEC"));textPaint.setStyle(Style.FILL_AND_STROKE);textPaint.setTextAlign(Align.LEFT);textPaint.setTextSize(mTextSize);// 上下文字的畫筆textPaint1 = new Paint(Paint.LINEAR_TEXT_FLAG);textPaint1.setAntiAlias(true);textPaint1.setColor(Color.parseColor("#a1a3a6"));textPaint1.setStyle(Style.FILL_AND_STROKE);textPaint1.setTextAlign(Align.LEFT);textPaint1.setTextSize(mTextSize1);// 中間文字內容mText = 0;// 扇形弧度mProgress = 0;// 動畫類anim = new BarAnimation();anim.setDuration(1000);}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {int halfHeight = getHeight() / 2;int halfWidth = getWidth() / 2;int radius = halfHeight < halfWidth ? halfHeight : halfWidth;// 圓圈的矩形範圍 繪製底部灰色圓圈的畫筆canvas.drawCircle(halfWidth, halfHeight, radius - 20f,mDefaultWheelPaint);// canvas.drawArc(mColorWheelRectangle, -90, 360, false,// mDefaultWheelPaint);// 為了達到藍色扇形增加效果而添加的變數,他和mSweepAngle其實代表一個意思// mColorWheelRectangle是繪製藍色扇形的畫筆mColorWheelRectangle.top = halfHeight - radius + 20f;mColorWheelRectangle.bottom = halfHeight + radius - 20f;mColorWheelRectangle.left = halfWidth - radius + 20f;mColorWheelRectangle.right = halfWidth + radius - 20f;// 根據mProgressAni(角度)畫扇形canvas.drawArc(mColorWheelRectangle, -90, mProgressAni, false,mColorWheelPaint);Rect bounds = new Rect();String middleText = null;// 中間的文字String upText = null;// 上面文字String downText = null;// 底部文字if (this.mType == 1) {// 第一個頁面upText = "步數";downText = "目標:10000";middleText = String.valueOf(mCount);} else if (this.mType == 2) {// 第二個頁面upText = "卡路裡";downText = "目標:10000";middleText = String.valueOf(mCount);} else if (this.mType == 3) {// 第三個頁面upText = "根據自己的需要填寫";downText = "3";middleText = "天氣";}// 中間文字的畫筆textPaint.getTextBounds(middleText, 0, middleText.length(), bounds);// drawText各個屬性的意思(文字,x座標,y座標,畫筆)canvas.drawText(middleText, (mColorWheelRectangle.centerX())- (textPaint.measureText(middleText) / 2),mColorWheelRectangle.centerY() + bounds.height() / 2, textPaint);textPaint1.getTextBounds(upText, 0, upText.length(), bounds);canvas.drawText(upText,(mColorWheelRectangle.centerX())- (textPaint1.measureText(upText) / 2),mColorWheelRectangle.centerY() + bounds.height() / 2- mDistance, textPaint1);textPaint1.getTextBounds(downText, 0, downText.length(), bounds);canvas.drawText(downText, (mColorWheelRectangle.centerX())- (textPaint1.measureText(downText) / 2),mColorWheelRectangle.centerY() + bounds.height() / 2+ mDistance, textPaint1);}// 測量父布局的大小protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int height = getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);int min = Math.min(width, height);setMeasuredDimension(min, min);mColorWheelRadius = min - circleStrokeWidth - pressExtraStrokeWidth;// set方法的參數意思:left,top,right,bottommColorWheelRectangle.set(circleStrokeWidth + pressExtraStrokeWidth,circleStrokeWidth + pressExtraStrokeWidth, mColorWheelRadius,mColorWheelRadius);}// 對外的一個介面,用來開啟動畫public void startCustomAnimation() {this.startAnimation(anim);}// 中間的數值public void setText(int text) {mText = text;this.postInvalidate();// 可以用子線程更新視圖的方法調用。}// 設定圓圈的進度和圓圈所顯示的第幾個頁面public void setProgress(float progress, int mType) {mProgress = progress;this.mType = mType;this.postInvalidate();// 可以用子線程更新視圖的方法調用。}/** * 繼承animation的一個動畫類 * * @author liyachao * */public class BarAnimation extends Animation {/** * Initializes expand collapse animation, has two types, collapse (1) * and expand (0). * * @param view * The view to animate * @param type * The type of animation: 0 will expand from gone and 0 size * to visible and layout size defined in xml. 1 will collapse * view and set to gone */@Overrideprotected void applyTransformation(float interpolatedTime,Transformation t) {super.applyTransformation(interpolatedTime, t);if (interpolatedTime < 1.0f) {mProgressAni = interpolatedTime * mProgress;mCount = (int) (interpolatedTime * mText);} else {mProgressAni = mProgress;mCount = mText;}postInvalidate();}}public static int dip2px(Context context, float dipValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dipValue * scale + 0.5f);}}
FragmentPedometer 的代碼如下
package com.example.histogram;import com.example.changepage1.R;import com.example.histogram.widet.CircleBar;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.View.OnClickListener;/** * 這是記步的片段 * Author: 李埡超 email:[email protected] * Date: 2015-1-2 * Time: 下午2:39 */public class FragmentPedometer extends Fragment{private View view;private CircleBar circleBar;private int type = 1;//頁面類型//需要在handler裡修改UIprivate Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {if (type == 1) {circleBar.setProgress(270, 1);circleBar.setText(1000);circleBar.startCustomAnimation();} else if (type == 2) {circleBar.setProgress(180, 2);circleBar.setText(1500);circleBar.startCustomAnimation();} else if (type == 3) {circleBar.setProgress(360, 3);circleBar.startCustomAnimation();}};};@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {view = inflater.inflate(R.layout.pedometer, container, false);circleBar = (CircleBar) view.findViewById(R.id.circle);circleBar.setProgress(270, 1);circleBar.setText(1000);circleBar.startCustomAnimation();//開啟動畫circleBar.setOnClickListener(new OnClickListener() {public void onClick(View view) {if (type == 1) {type = 2;} else if (type == 2) {type = 3;} else if (type == 3) {type = 1;}Message msg = new Message();handler.sendMessage(msg);}});return view;}}
基於Android的計步器(Pedometer)的講解(三)——CircleBar(圓形進度條)