<?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定义公共属性 <attr name="titleSize" format="dimension"></attr> <attr name="titleText" format="string"></attr> <attr name="titleColor" format="color"></attr> <attr name="outCircleColor" format="color"></attr> <attr name="inCircleColor" format="color"></attr> <attr name="lineColor" format="color"></attr> //自定义View的属性 <declare-styleable name="MyQQHealthView"> <attr name="titleColor"></attr> <attr name="lineColor"></attr> </declare-styleable> </resources>
<com.example.tangyangkai.myview.MyQQHealthView android:id="@+id/myQQView" android:layout_width="match_parent" android:layout_height="530dp" android:layout_margin="15dp" myQQ:lineColor="@color/font_tips" myQQ:titleColor="@color/textcolor" myQQ:titleSize="50dp" />
public MyQQHealthView(Context context) {
this(context, null);
}
public MyQQHealthView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyQQHealthView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取我们自定义的样式属性
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyQQHealthView, defStyleAttr, 0);
int n = array.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = array.getIndex(i);
switch (attr) {
case R.styleable.MyQQHealthView_titleColor:
// 默认颜色设置为黑色
textColor = array.getColor(attr, Color.BLACK);
break;
case R.styleable.MyQQHealthView_lineColor:
lineColor = array.getColor(attr, Color.BLACK);
break;
}
}
array.recycle();
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//如果布局里面设置的是固定值,这里取布局里面的固定值;如果设置的是match_parent,则取父布局的大小
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
//如果布局里面没有设置固定值,这里取布局的宽度的1/2
width = widthSize * 1 / 2;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
//如果布局里面没有设置固定值,这里取布局的高度的3/4
height = heightSize * 3 / 4;
}
widthBg = width;
heightBg = height;
setMeasuredDimension(width, height);
startAnim();
}
//绘制最底层的背景 radiusBg = widthBg / 20; pathBg.moveTo(0, heightBg); pathBg.lineTo(0, radiusBg); pathBg.quadTo(0, 0, radiusBg, 0); pathBg.lineTo(widthBg - radiusBg, 0); pathBg.quadTo(widthBg, 0, widthBg, radiusBg); pathBg.lineTo(widthBg, heightBg); pathBg.lineTo(0, heightBg); backgroundPaint.setColor(Color.WHITE); canvas.drawPath(pathBg, backgroundPaint);
//绘制圆弧 arcPaint.setStrokeWidth(widthBg / 20); //设置空心 arcPaint.setStyle(Paint.Style.STROKE); //防抖动 arcPaint.setDither(true); //连接处为圆弧 arcPaint.setStrokeJoin(Paint.Join.ROUND); //画笔的笔触为圆角 arcPaint.setStrokeCap(Paint.Cap.ROUND); arcPaint.setColor(lineColor); //圆弧范围 arcRect = new RectF(widthBg * 1 / 4, widthBg * 1 / 4, widthBg * 3 / 4, widthBg * 3 / 4); //绘制背景大圆弧 canvas.drawArc(arcRect, 120, 300, false, arcPaint); arcPaint.setColor(textColor); //绘制分数小圆弧 canvas.drawArc(arcRect, 120, arcNum, false, arcPaint);
//绘制圆圈内的数字
textPaint.setColor(textColor);
textPaint.setTextSize(widthBg / 10);
canvas.drawText(String.valueOf(walkNum), widthBg * 3 / 8, widthBg * 1 / 2 + 20, textPaint);
//绘制名次
textPaint.setTextSize(widthBg / 15);
canvas.drawText(String.valueOf(rankNum), widthBg * 1 / 2 - 15, widthBg * 3 / 4 + 10, textPaint);
//绘制其他文字
textPaint.setColor(lineColor);
textPaint.setTextSize(widthBg / 25);
canvas.drawText("截止13:45已走", widthBg * 3 / 8 - 10, widthBg * 5 / 12 - 10, textPaint);
canvas.drawText("好友平均2781步", widthBg * 3 / 8 - 10, widthBg * 2 / 3 - 20, textPaint);
canvas.drawText("第", widthBg * 1 / 2 - 50, widthBg * 3 / 4 + 10, textPaint);
canvas.drawText("名", widthBg * 1 / 2 + 30, widthBg * 3 / 4 + 10, textPaint);
//绘制圆圈外的文字
canvas.drawText("最近7天", widthBg * 1 / 15, widthBg, textPaint);
myaverageTxt = String.valueOf(averageSize);
canvas.drawText("平均", widthBg * 10 / 15 - 15, widthBg, textPaint);
canvas.drawText(myaverageTxt, widthBg * 11 / 15, widthBg, textPaint);
canvas.drawText("步/天", widthBg * 12 / 15 + 20, widthBg, textPaint);
//绘制虚线
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(2);
linePaint.setColor(lineColor);
linePath.moveTo(widthBg * 1 / 15, widthBg + 80);
linePath.lineTo(widthBg * 14 / 15, widthBg + 80);
linePaint.setPathEffect(effects);
canvas.drawPath(linePath, linePaint);
rectSize = widthBg / 12;
rectAgHeight = widthBg / 10;
//绘制虚线上的圆角竖线
for (int i = 0; i < FourActivity.sizes.size(); i++) {
rectPaint.setStrokeWidth(widthBg / 25);
rectPaint.setStyle(Paint.Style.STROKE);
rectPaint.setStrokeJoin(Paint.Join.ROUND);
rectPaint.setStrokeCap(Paint.Cap.ROUND);
float startHeight = widthBg + 90 + rectAgHeight;
rectPath.moveTo(rectSize, startHeight);
double percentage = Double.valueOf(FourActivity.sizes.get(i)) / Double.valueOf(averageSize);
double height = percentage * rectAgHeight;
rectPath.lineTo(rectSize, (float) (startHeight - height));
rectPaint.setColor(textColor);
canvas.drawPath(rectPath, rectPaint);
//绘制下方的文字
textPaint.setColor(lineColor);
canvas.drawText("0" + (i + 1) + "日", rectSize - 25, startHeight + 50, textPaint);
rectSize += widthBg / 7;
}
//绘制底部波纹
weavPaint.setColor(textColor);
weavPath.moveTo(0, heightBg);
weavPath.lineTo(0, heightBg * 10 / 12);
weavPath.cubicTo(widthBg * 1 / 10, heightBg * 10 / 12, widthBg * 3 / 10, heightBg * 11 / 12, widthBg, heightBg * 10 / 12);
weavPath.lineTo(widthBg, heightBg);
weavPath.lineTo(0, heightBg);
canvas.drawPath(weavPath, weavPaint);
//绘制底部文字
weavPaint.setColor(Color.WHITE);
weavPaint.setTextSize(widthBg / 20);
canvas.drawText("成绩不错,继续努力哟!", widthBg * 1 / 10 - 20, heightBg * 11 / 12 + 50, weavPaint);
private void startAnim() {
//步数动画的实现
ValueAnimator walkAnimator = ValueAnimator.ofInt(0, mySize);
walkAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
walkNum = (int) animation.getAnimatedValue();
postInvalidate();
}
});
//排名动画的实现
ValueAnimator rankAnimator = ValueAnimator.ofInt(0, rank);
rankAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rankNum = (int) animation.getAnimatedValue();
postInvalidate();
}
});
double size = mySize;
double avgSize = averageSize;
if (size > avgSize) {
size = avgSize;
}
//圆弧动画的实现
ValueAnimator arcAnimator = ValueAnimator.ofFloat(0, (float) (size / avgSize * 300));
arcAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
arcNum = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animSet.setDuration(3000);
animSet.playTogether(walkAnimator, rankAnimator, arcAnimator);
animSet.start();
}
public void reSet(int mysize, int myrank, int myaverageSize) {
walkNum = 0;
arcNum = 0;
rankNum = 0;
mySize = mysize;
rank = myrank;
averageSize = myaverageSize;
startAnim();
}
public class FourActivity extends AppCompatActivity {
private MyQQHealthView view;
public static List<Integer> sizes = new ArrayList<>();
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_four);
initview();
}
private void initview() {
view = (MyQQHealthView) findViewById(R.id.myQQView);
view.setMySize(2345);
view.setRank(11);
view.setAverageSize(5436);
sizes.add(1234);
sizes.add(2234);
sizes.add(4234);
sizes.add(6234);
sizes.add(3834);
sizes.add(7234);
sizes.add(5436);
btn = (Button) findViewById(R.id.set_btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.reSet(6534, 8, 4567);
}
});
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有