比分显示控件,自带两种动画

1.效果图

这是静态的,有两种动画,运行代码后能看到

2.代码

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 使用说明 <br/>
 * 1.XML定义<br/>
 * <com.longyuan.sdkdemo.CirclePieView <br/>
 * android:id="@+id/cpv" <br/>
 * android:layout_width="100dp" <br/>
 * android:layout_height="100dp" <br/>
 * android:layout_marginLeft="10dp" <br/>
 * android:layout_marginTop="10dp" > <br/>
 * </com.longyuan.sdkdemo.CirclePieView> <br/>
 * 2.设置比分<br/>
 * CirclePieView.setScore(4, 3, true, 1);<br/>
 * @author niexiaoqiang
 */
public class CirclePieView extends View {
	public int animationType = 1;
	public static final int E_C = 10;
	private int mWidth = 0;
	private int mHeight = 0;
	private int leftColor = Color.rgb(255, 255, 0);
	private int rightColor = Color.rgb(255, 0, 255);
	private int textBgColor = Color.rgb(255, 255, 255);
	private int bgColor = Color.rgb(0, 0, 0);
	//不能大于99
	private int leftScore = 0;
	//不能大于99
	private int rightScore = 0;
	private Paint textPaint;
	private Paint leftPaint;
	private Paint rightPaint;
	private Paint textBgPaint;
	private Paint bgPaint;
	private RectF drawRect = new RectF();
	private int circleWidth = 10;
	private int leftCircle = 180;
	private int rightCircle = 180;
	private int currentC = 360;
	//是否已经设置比分如果没有设置,则不绘制文字以及圆环
	private boolean initedScrore = false;
	private boolean stopped = true;

	private void init(Context context) {
		textPaint = new Paint();
		textPaint.setAntiAlias(true);
		textPaint.setColor(Color.BLACK);
		textPaint.setFakeBoldText(true);
		leftPaint = new Paint();
		leftPaint.setAntiAlias(true);
		leftPaint.setColor(leftColor);
		rightPaint = new Paint();
		rightPaint.setAntiAlias(true);
		rightPaint.setColor(rightColor);
		textBgPaint = new Paint();
		textBgPaint.setAntiAlias(true);
		textBgPaint.setColor(textBgColor);
		bgPaint = new Paint();
		bgPaint.setAntiAlias(true);
		bgPaint.setColor(bgColor);
		circleWidth = dip2px(context, 10);
	}

	public static int dip2px(Context context, float dipValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dipValue * scale + 0.5f);
	}

	/**
	 * 如果inited==false将不绘制比分,以及圆环
	 * @param initedScrore
	 */
	public void setInitedScrore(boolean initedScrore) {
		this.initedScrore = initedScrore;
		this.invalidate();
	}

	/**
	 * 调用该方法设置比分
	 * @param leftScore 左边的比分
	 * @param rightScore 右边的比分
	 * @param needAnimation 是否需要动画
	 * @param animationType 0: 旋转,1:展开
	 */
	public void setScore(int leftScore, int rightScore, boolean needAnimation, int animationType) {
		this.leftScore = leftScore;
		this.rightScore = rightScore;
		this.animationType = animationType;
		//计算占比
		if (leftScore == 0 && rightScore == 0) {
			leftCircle = 180;
		} else {
			leftCircle = (int) (((float) leftScore / (float) (leftScore + rightScore)) * (float) 360);
			leftCircle = leftCircle % 2 == 0 ? leftCircle : leftCircle - 1;
		}
		rightCircle = 360 - leftCircle;
		if (needAnimation) {
			currentC = 0;
			stopped = false;
		}
		setInitedScrore(true);
	}

	@Override
	public void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//背景
		canvas.drawCircle(mWidth / 2, mHeight / 2, (mWidth - 2) / 2, bgPaint);
		if (initedScrore) {
			//画圆
			drawRect.set(0, 0, mWidth, mHeight);
			int currentRightCircle = rightCircle * currentC / 360;
			if (animationType == 0) {
				canvas.drawArc(drawRect, 180 - leftCircle / 2, currentC, true, leftPaint);
				if (360 - currentC <= currentRightCircle) {
					canvas.drawArc(drawRect, 0 - rightCircle / 2, currentRightCircle, true, rightPaint);
				}
			} else {
				//画左边时以180°为中心,上下分别进行一次
				canvas.drawArc(drawRect, 180, leftCircle / 2 * currentC / 360, true, leftPaint);
				canvas.drawArc(drawRect, 180, -leftCircle / 2 * currentC / 360, true, leftPaint);
				//画右边时候以0°为中心,上下分别进行一次
				canvas.drawArc(drawRect, 0, rightCircle / 2 * currentC / 360, true, rightPaint);
				canvas.drawArc(drawRect, 0, -rightCircle / 2 * currentC / 360, true, rightPaint);
			}
		}
		//绘制文字背景
		canvas.drawCircle(mWidth / 2, mHeight / 2, (mWidth - circleWidth * 2) / 2, textBgPaint);
		if (initedScrore) {
			drawText(canvas);
		}
		currentC += E_C;
		if (currentC < 360) {
			postInvalidate();
			return;
		}
		if (currentC > 360) {
			currentC = 360;
		}
		if (!stopped) {
			postInvalidate();
			stopped = true;
		}
	}

	/**
	 * 画出文字
	 * @param canvas
	 */
	private void drawText(Canvas canvas) {
		/////////////最后画出文字//////////////
		int allTextWidth = mWidth - circleWidth * 2;
		textPaint.setTextSize(allTextWidth / 4 * currentC / 360);
		FontMetrics fontMetrics = textPaint.getFontMetrics();
		float textBaseLine = mHeight / 2 - ((fontMetrics.top - fontMetrics.bottom) / 2 + fontMetrics.bottom);
		//冒号
		String mindleString = ":";
		float mindleTextWidth = textPaint.measureText(mindleString);
		float midleTextleft = (allTextWidth - mindleTextWidth) / 2 + circleWidth;
		canvas.drawText(mindleString, midleTextleft, textBaseLine, textPaint);
		//标线
		//		canvas.drawLine(midleTextleft, 0, midleTextleft, mHeight, rightPaint);
		//		canvas.drawLine(midleTextleft + mindleTextWidth, 0, midleTextleft + mindleTextWidth, mHeight, rightPaint);
		//左边文字
		String leftString = getLeftString();
		float leftTextWidth = textPaint.measureText(leftString);
		float leftTextLeft = (midleTextleft - leftTextWidth) / 2 + circleWidth / 2;
		canvas.drawText(leftString, leftTextLeft, textBaseLine, textPaint);
		//标线
		//		canvas.drawLine(leftTextLeft, 0, leftTextLeft, mHeight, rightPaint);
		//		canvas.drawLine(leftTextLeft + leftTextWidth, 0, leftTextLeft + leftTextWidth, mHeight, rightPaint);
		//右边的文字
		String rightString = getRightString();
		float rightTextWidth = textPaint.measureText(rightString);
		float rightTextLeft = (midleTextleft + mindleTextWidth) + (allTextWidth - (midleTextleft + mindleTextWidth) - rightTextWidth) / 2 + circleWidth / 2;
		canvas.drawText(rightString, rightTextLeft, textBaseLine, textPaint);
		//标线
		//		canvas.drawLine(rightTextLeft, 0, rightTextLeft, mHeight, rightPaint);
		//		canvas.drawLine(rightTextLeft + rightTextWidth, 0, rightTextLeft + rightTextWidth, mHeight, rightPaint);
	}

	private String getLeftString() {
		if (leftScore < 10) {
			return "0" + leftScore;
		}
		return leftScore + "";
	}

	private String getRightString() {
		if (rightScore < 10) {
			return "0" + rightScore;
		}
		return rightScore + "";
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		mHeight = getMeasuredHeight();
		mWidth = getMeasuredWidth();
	}

	public CirclePieView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		this.init(context);
	}

	public CirclePieView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.init(context);
	}

	public CirclePieView(Context context) {
		super(context);
		this.init(context);
	}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-24 19:06:17

比分显示控件,自带两种动画的相关文章

[转]MFC子线程中更新控件内容的两种办法

一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线程中运行,而所有与主UI线程有关的控件数据刷新应该到主UI线程中处理.也就是数据处理线程发消息,让界面UI去更新控件.在MFC中线程分为界面线程和工作者线程,界面实际就是一个线程画出来的东西,这个线程维护一个"消息队列","消息队列"也是界面线程和工作者线程的最大区别,

MSCOMM32控件注册的两种办法

当我们在VC或者VB或者VS环境下基于MSCOMM控件开发的软件发布后,是不是有种很爽的感觉,可以拿到别人的电脑上运行下你的软件,可是当你移植过去后却发现软件无法点击的动(别笑,我在开发C#软件时就是这样)或者出现如下图所示的情况: 这种情况一般出现在Windows7版本下,这说明MSCOMM32没注册,我们可以选择两种方法去解决,一种方法是当我们安装VC++6.0/VB6.0时,如果选择了ACtiveX控件项(自定义安装),MSComm控件就会自动安装在计算机上了,并在系统文件夹下多了3个文件

[转] 基于C#的波形显示控件的实现

转自 基于C#的波形显示控件的实现[附完整源码下载] 编者记: 09年暑假正好在学院实验室呆了一段时间,做了个完整的上位机软件(具体实现:根据下位机的指令,实现通过串口来操纵下位机进行实验,并将采集的数据进行处理和保存,并以图形的方式显示),整个项目边学C# WinForm边设计,这个波形显示控件就是项目中的一部分,也花了自己绝大多数时间.此外,顺便将该波形显示控件当作自己毕业设计的内容,下文实际上是节选自自己的本科毕业论文,希望对大家能有所帮助.代码以及文章有疏漏.错误.不妥之处在所难免,欢迎

控件绘制的四种方法

OWNER?DRAW实现自绘按钮 一准备工作 在您决定开发 Windows 提供的常规免费自定义控件范围之外的控件之后,您必需确定自己的控件将有多少独到之处 - 在功能和外观两方面.例如,我们假定您正在创建一个类似于计速表的控件.由于公共控件库 (ComCtrl32.dll) 中没有类似的控件,您完全需要自己进行以下操作:编写所有控件功能需要的代码,进行绘制,默认终端用户的交互,以及控件与其父窗口之间需要的任意消息处理. (#add 两方面,公共控件库中没有类似的 完全重写;? 只想调整公共控件

android控件---自定义带文本的ImageButton

由于SDK提供的ImageButton只能添加图片,不能添加文字:而Button控件添加的文字只能显示在图片内部:当我们需要添加文字在图片外部时就不能满足我们的需求了,顾只能自己写个自定义ImageButton.说是ImageButton,其实并不是继承于ImageButton,而是从LinearLayout继承,由于LinearLayout是线性排列,通过setOrientation(LinearLayout.VERTICAL)的方式达到View垂直排列的目的,所以很简单,只需要添加两个Vie

QT5:基础篇 第七章 显示控件

一.简介 在显示控件(Display Widgets)中,有10种类型的显示控件 Label Text Browser Graphics View Calendar Widget LCD Number Progress Bar Horizontal Line Vertical Line OpenGL Widget QQuickWidget 二.Label #include <QLable> int main(int argc, char* argv[]) { QLabel* label = n

动态图片显示控件----------WinForm控件开发系列

PictureBox控件无法显示gif格式的图片,该控件利用.NET自带ImageAnimator类来处理图片的帧. /// <summary> /// 动态图片显示控件 /// </summary> [ToolboxItem(true)] [DefaultProperty("Image")] [Description("动态图片显示控件")] public partial class AnimationImageExt : Control

delphi 窗体只显示控件

procedure TForm1.FormCreate(Sender: TObject);begin    BorderStyle := bsNone;    Brush.Style := bsClear;end; delphi 窗体只显示控件,布布扣,bubuko.com

Android中EditText显示明文与密文的两种方式

效果图   布局文件 <?xml version="1.0" encoding="utf-8"?> <!-- Android中EditText显示明文与密文的两种方式 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/to