基于Android的计步器(Pedometer)的讲解(三)——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")
	@Override
	protected 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,bottom
		mColorWheelRectangle.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
		 */
		@Override
		protected 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里修改UI
	private 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();
			}
		};
	};

	@Override
	public 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;
	}

}
时间: 2024-10-07 09:09:26

基于Android的计步器(Pedometer)的讲解(三)——CircleBar(圆形进度条)的相关文章

基于Android的计步器(Pedometer)的讲解(四)——后台记步

今天先不说Pedometer(计步器)项目UI方面的了,今天讲一个基于重力加速度的记步功能传感器(Sensor),然后 在后台开启记步. 计步器(Pedometer)整个项目的源代码,感兴趣的朋友可以下载来看看(记得帮小弟在github打个星~) https://github.com/296777513/pedometer 先上几张效果图:(效果和上一篇讲到的CircleBar非常的相似,因为记步功能在后台) 如图所示,能根据你的一些基本参数,来记步.有一个缺点,因为这个是根据感应加速度来计算是

基于Android的计步器(Pedometer)的讲解(二)——柱状图分析

写正文之前,小小的吐槽一下,还有一个月就放假了,作业.考试.还有实习(研一,下半学期课不多,也不想在实验室)的考虑,最近基于hadoop的数据分析马上也要验收了,真的忙的"外焦里嫩"啊!目前定的方向是Android开发,所以想过年来了找一个Android的实习工作,提高一点在真正的项目中的经验. 好了,说了这么多废话,开始进入正题吧. 整个计步器的项目已经上传到github上了,感兴趣的朋友可以去看看(最好能给小弟我打颗星星哦~) https://github.com/29677751

基于Android的计步器(Pedometer)的讲解(五)——跟随界面滑动的指示器

计步器(Pedometer)整个项目的源代码,感兴趣的朋友可以下载来看看(记得帮小弟在github打个星~) https://github.com/296777513/pedometer 今天,说下指示器随着界面滑动,可能这样说不太直观,我先附上几张效果图: 如图所示,中间部分为一个ViewPager(可以滑动的页面),大家可以看到屏幕的顶部,字体下面有一个指示器, 当页面向右滑动时,指示器也会随着界面动态的向右滑动,当页面停在第二个页面时,字体也会变为蓝色. 下来给大家贴出主要的代码: pac

基于Android的计步器(Pedometer)的讲解-序(修改)

今天本来想说listview中的下拉刷新数据的,但是突然想到一些比较好的想法. 用了一天的时间将Pedometer这个项目其中的网络功能.照片和一些逻辑功能做了修改,所以在这里有必要和大家讲一下,以前下载的Pedometer程序可能不能运行了. 计步器(Pedometer)整个项目的源代码,感兴趣的朋友可以下载来看看(记得帮小弟在github打个星~) https://github.com/296777513/pedometer 头像由以前的路径存储变为二进制存储,这样大家可以看到传到网上的头像

基于Android的计步器(Pedometer)的讲解(六)——ListView下拉刷新页面

计步器(Pedometer)整个项目的源代码,最近做了比较大的修改,可能以前下载的不能运行,感兴趣的朋友可以下载来看看(记得帮小弟在github打个星~) https://github.com/296777513/pedometer 今天实现实现的下拉刷新的功能,先上几张效果图: 如图所示,今天就是要实现的这个效果 首先,分析ListView下拉刷新实现方式 1.需要添加顶部下拉加载页面 2.需要监听onScrollListener来判断当前是否显示在listview的最顶部 3.因为顶部下拉加

基于Android的计步器(Pedometer)的讲解(一)——Fragment页面跳转

首先需要做的是实现几个页面的跳转,既类似微信的点击按钮,切换页面. 话不多说,这是一个简单的页面切换的Demo,先贴几张实现的效果: 图片的底部是5个RadioButton,用来进行页面之间的切换.剩下的部分是一个LinearLayout的布局,用来镶嵌5个Fragment(碎片)的页面. 一共用到5个类:MainActivity.MyAdapter.FragmentHistory.FragmentAnalysis.FragmentPedometer.FragmentPK.FragmentSet

【Android进度条】三种方式实现自定义圆形进度条ProgressBar

一.通过动画实现 定义res/anim/loading.xml如下: [html] view plaincopyprint? <?xml version="1.0" encoding="UTF-8"?> <animation-list android:oneshot="false" xmlns:android="http://schemas.android.com/apk/res/android"> &

【转】Android UI系列-----时间、日期、Toasts和进度条Dialog

原文网址:http://www.cnblogs.com/xiaoluo501395377/p/3421727.html 您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内容有任何疑问, 可以通过评论或发邮件的方式联系我: [email protected] / [email protected] 如果需要转载,请注明出处,谢谢!! 本篇随笔将继续学

Android自定义View——圆形进度条式按钮

介绍 今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图. 和普通的圆形进度条类似,只是中间的地方有两个状态表示,未开始,暂停状态.而且他说圆形进度的功能已经实现了.那么我们只需要对中间的两个状态做处理就行了. 先来看看实现的效果图: 上面说了我们只需要处理中间状态的变化就可以了,对于进度的处理直接使用了弘洋文章中实现: http://blog.csdn.net/lmj623565791/article/details/43371299 下面开始具体实现. 具体实