先上图看一下闹钟唤期页面的效果

实现的功能:

1:转动的图片根据天气情况更换

2:转动时间可以设置,转动结束,闹铃声音就结束

3:光圈颜色渐变效果

直接上代码啦:

package com.yuekong.sirius.extension.customview;

import android.animation.Animator;

import android.animation.ValueAnimator;

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.graphics.Paint;

import android.graphics.Rect;

import android.graphics.RectF;

import android.graphics.SweepGradient;

import android.media.Ringtone;

import android.media.RingtoneManager;

import android.net.Uri;

import android.util.AttributeSet;

import android.util.TypedValue;

import android.view.View;

import android.view.animation.LinearInterpolator;

import com.yuekong.sirius.extension.R;

import com.yuekong.sirius.extension.util.ExtendUtil;

import java.text.SimpleDateFormat;

/**

* Created by Zhongqi.Shao on 2016/12/5.

*/

public class ClockWakeView extends View {

//最外一层圆的颜色

private int mOutCircleColor;

//最外一层圆的半径

private int mOutCircleRadis;

//内圆的颜色

private int mInnerCircleColor;

//内圆的半径

private int mInnerCircleRadis;

private int mWidth;

private int mHeight;

//默认宽度

private final int DEFAULT_WIDTH = dp2px(240);

//默认高度

private final int DEFAULT_HEIGHT = dp2px(240);

//最外圆的默认半径

private int DEFAULT_OUT_RADIS = dp2px(120);

//内圆的默认半径

private int DeFAULT_INNER_RADIS = dp2px(105);

//标题距离顶部的默认距离

private int DEFAULT_TITLE_PADDING_TOP = dp2px(40);

//最外层圆形的Paint

private Paint mOutCirclePaint;

//内圆的Paint

private Paint mInnerCirclePaint;

//标题Paint

private Paint mTitlePaint;

//渐变弧

private Paint mGradientArcPaint;

private SweepGradient mSweepGradient;

//日期时间Paint

private Paint mTimePaint;

private Paint mDatePaint;

//时间分隔的图片

private Bitmap mDividerPic;

//天气图片

private Bitmap mWeatherPic;

//标题

private String mTitle;

//当前时间

private long mCurrentDate = 1481010829605L;

private SimpleDateFormat mFormat;

private Ringtone mRingTone;

//图片在倒计时几分钟内走完一个周期 根据音乐时间来计算

private long mCountDownTime;

//倒计时转过的角度

private float mCurrentAngle;

//倒计时结束回调

private CountdownFinishListener mCountdownListener;

private Context mContext;

public ClockWakeView(Context context) {

this(context, null);

mContext = context;

}

public ClockWakeView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

mContext = context;

}

public ClockWakeView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mContext = context;

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SiriusClockWakeView);

mOutCircleColor = ta.getColor(R.styleable.SiriusClockWakeView_outColor, context.getResources().getColor(R.color.out_circle_color));

mOutCircleRadis = (int) ta.getDimension(R.styleable.SiriusClockWakeView_outCircleRadis, DEFAULT_OUT_RADIS);

mInnerCircleColor = context.getResources().getColor(R.color.inner_circle_color);

mInnerCircleRadis = DeFAULT_INNER_RADIS;

mTitle = context.getResources().getString(R.string.clock);

ta.recycle();

initPaint();

}

private void initPaint() {

mFormat = new SimpleDateFormat("MM月dd日_HH_mm_EEEE");

//获取分隔图片

mDividerPic = BitmapFactory.decodeResource(getResources(), R.drawable.time_divider);

mWeatherPic = BitmapFactory.decodeResource(getResources(), R.drawable.icon_weather);

//外圆的paint

mOutCirclePaint = new Paint();

mOutCirclePaint.setAntiAlias(true);

mOutCirclePaint.setStyle(Paint.Style.STROKE);

mOutCirclePaint.setStrokeWidth(dp2px(5));

mOutCirclePaint.setColor(mOutCircleColor);

//内圆的Paint

mInnerCirclePaint = new Paint();

mInnerCirclePaint.setAntiAlias(true);

mInnerCirclePaint.setStyle(Paint.Style.STROKE);

mInnerCirclePaint.setStrokeWidth(dp2px(5));

mInnerCirclePaint.setColor(mInnerCircleColor);

//标题的Paint

mTitlePaint = new Paint();

mTitlePaint.setAntiAlias(true);

mTitlePaint.setStyle(Paint.Style.FILL);

mTitlePaint.setColor(mContext.getResources().getColor(R.color.nav_highlighted));

mTitlePaint.setTextSize(sp2px(14));

//时间的Paint

mTimePaint = new Paint();

mTimePaint.setAntiAlias(true);

mTimePaint.setColor(Color.WHITE);

mTimePaint.setStyle(Paint.Style.FILL);

mTimePaint.setTextSize(sp2px(70));

//日期的Paint

mDatePaint = new Paint();

mDatePaint.setAntiAlias(true);

mDatePaint.setColor(Color.WHITE);

mDatePaint.setStyle(Paint.Style.FILL);

mDatePaint.setTextSize(sp2px(14));

//渐变弧的Paint

mGradientArcPaint = new Paint();

mGradientArcPaint.setAntiAlias(true);

mGradientArcPaint.setStyle(Paint.Style.STROKE);

mGradientArcPaint.setStrokeWidth(dp2px(5));

mGradientArcPaint.setStrokeCap(Paint.Cap.BUTT);

mGradientArcPaint.setStrokeJoin(Paint.Join.MITER);

//设置渐变的颜色

int[] colors = {0x00AEA1FF, 0x40AEA1FF, 0xFFAEA1FF, 0xFFAEA1FF};

//渐变色

mSweepGradient = new SweepGradient(0, 0, colors, null);

mGradientArcPaint.setShader(mSweepGradient);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

mWidth = startMeasure(widthMeasureSpec);

mHeight = startMeasure(heightMeasureSpec);

setMeasuredDimension(mWidth, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//移动画布到中间

canvas.translate(mWidth / 2, mHeight / 2);

//绘制最外层的圆形

drawOutCircle(canvas);

//绘制内圆

drawInnerCircle(canvas);

//绘制中间的分隔图片

drawDividerPic(canvas);

//绘制标题

drawTitle(canvas);

//绘制时间

drawDateTime(canvas);

//绘制旋转图片

drawLightArc(canvas);

}

private void drawOutCircle(Canvas canvas) {

canvas.save();

canvas.drawCircle(0, 0, mOutCircleRadis, mOutCirclePaint);

canvas.restore();

}

private void drawInnerCircle(Canvas canvas) {

canvas.save();

canvas.drawCircle(0, 0, mInnerCircleRadis, mInnerCirclePaint);

canvas.restore();

}

private void drawDividerPic(Canvas canvas) {

canvas.save();

canvas.drawBitmap(mDividerPic, null, new Rect(-dp2px(3), -dp2px(14), dp2px(3), dp2px(14)), null);

canvas.restore();

}

private void drawTitle(Canvas canvas) {

canvas.save();

if (mTitle == null || mTitle.length() <= 0) {

return;

}

float textWidth = mTitlePaint.measureText(mTitle);

float baseLine = DeFAULT_INNER_RADIS - DEFAULT_TITLE_PADDING_TOP;

canvas.drawText(mTitle, -textWidth / 2, -baseLine, mTitlePaint);

canvas.restore();

}

private void drawLightArc(Canvas canvas) {

canvas.save();

canvas.rotate(mCurrentAngle);

RectF rect = new RectF(-mInnerCircleRadis, -mInnerCircleRadis, mInnerCircleRadis, mInnerCircleRadis);

canvas.drawArc(rect, -270, 180, false, mGradientArcPaint);

canvas.drawBitmap(mWeatherPic, null, new Rect(-dp2px(12), -mInnerCircleRadis - dp2px(12), dp2px(12), dp2px(12) - mInnerCircleRadis), null);

canvas.restore();

}

private void drawDateTime(Canvas canvas) {

canvas.save();

String timeStr = ExtendUtil.getAllFormatStr(mFormat, mCurrentDate);

String[] array = timeStr.split("_");

String date = array[0];

String hour = array[1];

String minute = array[2];

String wake = array[3];

float width = mTimePaint.measureText(hour);

RectF targetRect = new RectF(-(width + dp2px(40)), -sp2px(70) / 2, -dp2px(40), sp2px(70) / 2);

Paint.FontMetricsInt fontMetrics = mTimePaint.getFontMetricsInt();

int baseline = (int) (targetRect.top + (targetRect.bottom - targetRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top);

canvas.drawText(hour, -width - dp2px(15), baseline, mTimePaint);

float minuteWidth = mTimePaint.measureText(minute);

RectF minuteRect = new RectF(dp2px(15), -sp2px(70) / 2, dp2px(15) + minuteWidth, sp2px(70) / 2);

Paint.FontMetricsInt minuteMetrics = mTimePaint.getFontMetricsInt();

int minuteLine = (int) (minuteRect.top + (minuteRect.bottom - minuteRect.top - minuteMetrics.bottom + minuteMetrics.top) / 2 - minuteMetrics.top);

canvas.drawText(minute, dp2px(15), minuteLine, mTimePaint);

String dateStr = date + " " + wake;

float dateWidth = mDatePaint.measureText(dateStr);

RectF dateRect = new RectF(-dateWidth / 2, sp2px(30), dateWidth / 2, sp2px(30) + sp2px(14));

Paint.FontMetricsInt dateMetrics = mTimePaint.getFontMetricsInt();

int dateLine = (int) (dateRect.top + (dateRect.bottom - dateRect.top - dateMetrics.bottom + dateMetrics.top) / 2 - dateMetrics.top);

canvas.drawText(dateStr, -dateWidth / 2, dateLine, mDatePaint);

canvas.restore();

}

private int startMeasure(int whSpec) {

int result = 0;

int size = MeasureSpec.getSize(whSpec);

int mode = MeasureSpec.getMode(whSpec);

if (mode == MeasureSpec.EXACTLY) {

result = size;

} else {

result = DEFAULT_WIDTH;

}

return result;

}

//开始倒计时计算闹钟结束

public void startCountDown() {

ValueAnimator animator = ValueAnimator.ofFloat(0, 1.0f);

animator.setDuration(mCountDownTime);

//匀速

animator.setInterpolator(new LinearInterpolator());

//不循环

animator.setRepeatCount(0);

//监听动画过程中值得实时变化

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator valueAnimator) {

mCurrentAngle = (float) valueAnimator.getAnimatedValue() * 360;

invalidate();

}

});

animator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animator) {

}

@Override

public void onAnimationEnd(Animator animator) {

if (mRingTone != null && mRingTone.isPlaying()) {

mRingTone.stop();

}

if (mCountdownListener != null) {

mCountdownListener.countdownFinished();

}

}

@Override

public void onAnimationCancel(Animator animator) {

}

@Override

public void onAnimationRepeat(Animator animator) {

}

});

animator.start();

//播放闹钟铃声

Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);

mRingTone = RingtoneManager.getRingtone(mContext, notification);

if (mRingTone != null && !mRingTone.isPlaying()) {

mRingTone.play();

}

}

//提供设置倒计时的方法

public void setCountDownTime(long time, CountdownFinishListener listener) {

mCountDownTime = time;

mCountdownListener = listener;

}

//设置当前日期时间

public void setCurrentTime(long currentTime) {

mCurrentDate = currentTime;

invalidate();

}

private int dp2px(int dp) {

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());

}

private int sp2px(int sp) {

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());

}

public interface CountdownFinishListener {

//倒计时结束操作

void countdownFinished();

}

}

以上所述是小编给大家介绍的Android自定义View 实现闹钟唤起播放闹钟铃声功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

Android5.0自定义闹钟,Android自定义View 实现闹钟唤起播放闹钟铃声功能相关推荐

  1. android如何自定义dialog,Android—自定义Dialog

    在 Android 日常的开发中,Dialog 使用是比较广泛的.无论是提示一个提示语,还是确认信息,还是有一定交互的(弹出验证码,输入账号密码登录等等)对话框. 而我们去看一下原生的对话框,虽然随着 ...

  2. Android自定义View 闹钟唤起播放闹钟铃声实现

    先上图看一下闹钟唤期页面的效果 实现的功能: 1:转动的图片根据天气情况更换 2:转动时间可以设置,转动结束,闹铃声音就结束 3:光圈颜色渐变效果 直接上代码啦: package com.exampl ...

  3. android 自定义图形,Android自定义View之图形图像(模仿360的刷新球自定

    概述: 360安全卫士的那个刷新球(姑且叫它刷新球,因为真的不知道叫什么好,不是dota里的刷新球!!),里面像住了水一样,生动可爱,看似简单,写起来不太简单,本例程只是实现了它的部分功能而已,说实话 ...

  4. Android 自定义 圆环,Android自定义view实现圆环效果实例代码

    先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...

  5. android自定义抽奖,Android自定义view制作抽奖转盘

    本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...

  6. android 自定义 child,Android自定义View

    前言 Android自定义View的详细步骤是我们每一个Android开发人员都必须掌握的技能,因为在开发中总会遇到自定义View的需求.为了提高自己的技术水平,自己就系统的去研究了一下,在这里写下一 ...

  7. android 自定义 对号,Android自定义View实现打钩动画功能

    先上效果图 动图 静态图 1. 回顾 [Android自定义View:一个精致的打钩小动画]上一篇文章,我们已经实现了基本上实现了控件的效果了,但是...但是...过了三四天后,仔细看回自己写的代码, ...

  8. android自定义虚线,Android自定义view的方式绘制虚线

    Android自定义view绘制虚线 最近项目中有个需求,通过自定义view的方式绘制虚线 别的不多说先看一眼效果 这个需求在我们的开发中应该是一个很常见的需求了吧,有人会说有更简单的实现方式,对,但 ...

  9. android 自定义特效,Android自定义View之高仿QQ健康

    我们都知道自定义View一般有三种直接继承View.继承原有的控件对控件的进行修改.重新拼装组合,最后一种主要针对于ViewGroup.具体的怎么做不是本文的所涉及的内容(本文是基于第一种方式实现的) ...

最新文章

  1. A monad tutorial for Clojure programmers (part 3)
  2. java mysql in_MySQL中Exists和In的使用
  3. Linux学习笔记033_8文本处理
  4. 拿不到offer全额退款 | 第四期人工智能 NLP / CV 课 培训招生
  5. python数据结构教程_利用Python演示数型数据结构的教程
  6. qt往mysql中添加数据_qt往数据库添加数据
  7. 如何将彩色网页内容变成灰白的
  8. linux 7 network fail,CentOs7 网卡出现问题Job for network.service failed
  9. Linux,begin
  10. 傅里叶变换 相位谱 幅度谱
  11. 数据仓库实践-拉链表设计
  12. Problem A. Snapper Chain 问题A.按扣链条 解决办法
  13. 快速删除大文件利器 node 包 rimraf
  14. windows 睡眠倒计时_如何在手机上设置音乐睡眠计时器
  15. 2023年五一数学建模竞赛ABC题思路资料汇总贴
  16. win10 raw linux ntfs,win10升级后磁盘变成RAW格式无法访问
  17. YTU 3386 哈希查找2
  18. CE下中文输入法编辑器(转)
  19. yjp-9.5.6使用
  20. 园区智慧安防解决方案2020

热门文章

  1. email邮箱情缘:《电子情书 You've Got Mail》
  2. 写个贺词,祝贺销售额业绩突破千万,要引经据典,对未来有所展望。
  3. 控制反转( IoC)和依赖注入(DI)
  4. VMware上面运行思科IOS XR的一些提示。
  5. 电脑输入法不能切换的解决办法
  6. 火锅馆取名支那引发公愤续:老板下跪道歉
  7. 【Python学习教程】Python列表(list)、元组(tuple)、字典(dict)和集合(set)详解
  8. arduino的servo函数_如何使用Arduino舵机库servo.h – 八色木
  9. 2019最新Windows上安装并启动ElasticSearch6.5.4
  10. 要看计算机的cpu型号和内存大小,怎样查看电脑的CPU型号和存储空间