欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义View 实现闹钟唤起播放闹钟铃声功能

程序员文章站 2024-02-28 20:39:10
先上图看一下闹钟唤期页面的效果 实现的功能: 1:转动的图片根据天气情况更换 2:转动时间可以设置,转动结束,闹铃声音就结束 3:光圈颜色渐变效果 直接上代码...

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

Android自定义View 实现闹钟唤起播放闹钟铃声功能Android自定义View 实现闹钟唤起播放闹钟铃声功能Android自定义View 实现闹钟唤起播放闹钟铃声功能

实现的功能:

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 实现闹钟唤起播放闹钟铃声功能,希望对大家有所帮助