Android自定义View 实现闹钟唤起播放闹钟铃声功能
程序员文章站
2024-02-28 20:39:10
先上图看一下闹钟唤期页面的效果
实现的功能:
1:转动的图片根据天气情况更换
2:转动时间可以设置,转动结束,闹铃声音就结束
3:光圈颜色渐变效果
直接上代码...
先上图看一下闹钟唤期页面的效果
实现的功能:
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 实现闹钟唤起播放闹钟铃声功能,希望对大家有所帮助