Android自定義模擬時(shí)鐘控件
本文實(shí)例為大家分享了Android自定義模擬時(shí)鐘控件的具體代碼,供大家參考,具體內(nèi)容如下
自定義view—透明模擬時(shí)鐘顯示
項(xiàng)目中要用到模擬時(shí)鐘的顯示,查了一些資料根據(jù)自己的需要進(jìn)行了自定義view
思路:重寫view,1.根據(jù)控件的寬高進(jìn)行獲取模擬時(shí)鐘的半徑大小。2.重寫onDraw方法,將畫布進(jìn)行不同角度的旋轉(zhuǎn)進(jìn)行繪制表盤 圓心 刻度 指針
這里就直接上代碼了
自定義的TimeClockView:
package com.eq.viewdemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.text.TextPaint; import android.util.AttributeSet; import android.view.View; import java.util.Calendar; /** ?* Created by pc on 2017/3/29. ?*/ public class TimeClockView extends View { ? ? private int width; ? ? private int height; ? ? private Paint mPaintLine; ? ? private Paint mPaintCircle; ? ? private Paint mPaintHour; ? ? private Paint mPaintMinute; ? ? private Paint mPaintSec; ? ? private TextPaint mPaintText; ? ? private Calendar mCalendar; ? ? public static final int START_ONDRAW = 0X23; ? ? //每隔一秒,在handler中調(diào)用一次重新繪制方法 ? ? private Handler handler = new Handler() { ? ? ? ? @Override ? ? ? ? public void handleMessage(Message msg) { ? ? ? ? ? ? switch (msg.what) { ? ? ? ? ? ? ? ? case START_ONDRAW: ? ? ? ? ? ? ? ? ? ? mCalendar = Calendar.getInstance(); ? ? ? ? ? ? ? ? ? ? invalidate();//告訴UI主線程重新繪制 ? ? ? ? ? ? ? ? ? ? handler.sendEmptyMessageDelayed(START_ONDRAW, 1000); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? } ? ? }; ? ? public TimeClockView(Context context) { ? ? ? ? super(context); ? ? } ? ? public TimeClockView(Context context, AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? mCalendar = Calendar.getInstance(); ? ? ? ? mPaintLine = new Paint(); ? ? ? ? mPaintLine.setColor(Color.GREEN); ? ? ? ? mPaintLine.setStrokeWidth(2); ? ? ? ? mPaintLine.setAntiAlias(true);//設(shè)置是否抗鋸齒 ? ? ? ? mPaintLine.setStyle(Paint.Style.STROKE);//設(shè)置繪制風(fēng)格 ? ? ? ? mPaintCircle = new Paint(); ? ? ? ? mPaintCircle.setColor(Color.RED);//設(shè)置顏色 ? ? ? ? mPaintCircle.setStrokeWidth(2);//設(shè)置線寬 ? ? ? ? mPaintCircle.setAntiAlias(true);//設(shè)置是否抗鋸齒 ? ? ? ? mPaintCircle.setStyle(Paint.Style.FILL);//設(shè)置繪制風(fēng)格 ? ? ? ? mPaintText = new TextPaint(); ? ? ? ? mPaintText.setColor(Color.BLUE); ? ? ? ? mPaintText.setStrokeWidth(5); ? ? ? ? mPaintText.setTextAlign(Paint.Align.CENTER); ? ? ? ? mPaintText.setTextSize(30); ? ? ? ? mPaintHour = new Paint(); ? ? ? ? mPaintHour.setStrokeWidth(6); ? ? ? ? mPaintHour.setColor(Color.BLUE); ? ? ? ? mPaintHour.setAntiAlias(true); ? ? ? ? mPaintMinute = new Paint(); ? ? ? ? mPaintMinute.setStrokeWidth(4); ? ? ? ? mPaintMinute.setColor(Color.BLUE); ? ? ? ? mPaintMinute.setAntiAlias(true); ? ? ? ? mPaintSec = new Paint(); ? ? ? ? mPaintSec.setStrokeWidth(2); ? ? ? ? mPaintSec.setColor(Color.BLUE); ? ? ? ? mPaintSec.setAntiAlias(true); ? ? ? ? handler.sendEmptyMessage(START_ONDRAW);//向handler發(fā)送一個(gè)消息,讓它開啟重繪 ? ? } ? ? @Override ? ? protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ? ? ? ? super.onMeasure(widthMeasureSpec, heightMeasureSpec); ? ? ? ? width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); ? ? ? ? height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); ? ? ? ? setMeasuredDimension(width, height); ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? super.onDraw(canvas); ? ? ? ? int circleRadius ; //模擬時(shí)鐘的圓半徑大小 ? ? ? ? if (width > height) { ? ? ? ? ? ? circleRadius = height / 2 -10; ? ? ? ? } else { ? ? ? ? ? ? circleRadius = width / 2 -10; ? ? ? ? } ? ? ? ? //畫出圓中心 ? ? ? ? canvas.drawCircle(width / 2, height / 2, 5, mPaintCircle); ? ? ? ? //依次旋轉(zhuǎn)畫布,畫出每個(gè)刻度和對(duì)應(yīng)數(shù)字 ? ? ? ? for (int i = 1; i <= 60; i++) { ? ? ? ? ? ? canvas.save();//保存當(dāng)前畫布 ? ? ? ? ? ? if (i % 5 == 0) { ? ? ? ? ? ? ? ? //將畫布進(jìn)行以圓心以固定的角度旋轉(zhuǎn)進(jìn)行旋轉(zhuǎn) ? ? ? ? ? ? ? ? canvas.rotate(360 / 60 * i, width / 2, height / 2); ? ? ? ? ? ? ? ? //設(shè)置字體大小,這里是以圓半徑的十分之一大小 ? ? ? ? ? ? ? ? mPaintText.setTextSize(circleRadius / 10); ? ? ? ? ? ? ? ? //如果繪制對(duì)應(yīng)的數(shù)字時(shí)只進(jìn)行一次旋轉(zhuǎn)是不能達(dá)到目標(biāo)的,需要再次以書寫文字的地方在進(jìn)行反向旋轉(zhuǎn)這樣寫出來的就是正向的 ? ? ? ? ? ? ? ? canvas.rotate(-360 / 60 * i, width / 2, height / 2 - circleRadius+5); ? ? ? ? ? ? ? ? canvas.drawText("" + i / 5, width / 2, height / 2 - circleRadius+circleRadius / 20 , mPaintText); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? canvas.rotate(360 / 60 * i, width / 2, height / 2); ? ? ? ? ? ? ? ? //左起:起始位置x坐標(biāo),起始位置y坐標(biāo),終止位置x坐標(biāo),終止位置y坐標(biāo),畫筆(一個(gè)Paint對(duì)象) ? ? ? ? ? ? ? ? canvas.drawCircle(width/2,height/2-circleRadius,2,mPaintCircle); ? ? ? ? ? ? } ? ? ? ? ? ? canvas.restore(); ? ? ? ? } ? ? ? ? int minute = mCalendar.get(Calendar.MINUTE);//得到當(dāng)前分鐘數(shù) ? ? ? ? int hour = mCalendar.get(Calendar.HOUR);//得到當(dāng)前小時(shí)數(shù) ? ? ? ? int sec = mCalendar.get(Calendar.SECOND);//得到當(dāng)前秒數(shù) ? ? ? ? String time; ? ? ? ? if (sec < 10 && hour < 10 && minute < 10) { //都小于10 ? ? ? ? ? ? time = "0" + hour + ":0" + minute + ":0" + sec; //02:02:02 ? ? ? ? } else if (sec < 10 && hour < 10 && minute > 9) {//分鐘大于9 ? ? ? ? ? ? time = "0" + hour + ":" + minute + ":0" + sec; //02:12:02 ? ? ? ? } else if (sec > 9 && hour < 10 && minute < 10) {//秒大于9 ? ? ? ? ? ? time = "0" + hour + ":0" + minute + ":" + sec; //02:02:12 ? ? ? ? } else if (sec < 10 && hour > 9 && minute < 10) {//時(shí)大于9 ? ? ? ? ? ? time = hour + ":0" + minute + ":0" + sec; //12:02:02 ? ? ? ? } else if (sec < 10 && hour > 9 && minute > 9) {//時(shí)分于9 ? ? ? ? ? ? time = hour + ":" + minute + ":0" + sec; //12:12:02 ? ? ? ? } else if (sec > 9 && hour > 9 && minute < 10) {//時(shí)秒大于9 ? ? ? ? ? ? time = hour + ":0" + minute + ":" + sec; //12:02:12 ? ? ? ? } else if (sec > 9 && hour < 10 && minute > 9) {//分秒大于9 ? ? ? ? ? ? time = "0" + hour + ":" + minute + ":" + sec; //02:12:12 ? ? ? ? } else { ? ? ? ? ? ? time = hour + ":" + minute + ":" + sec; //12:12:12 ? ? ? ? } ? ? ? ? //繪制中心下方的時(shí)間顯示 ? ? ? ? mPaintText.setTextSize(circleRadius / 10 * 2); ? ? ? ? canvas.save(); ? ? ? ? canvas.drawText(time, width / 2, height / 2 + circleRadius / 10 * 4, mPaintText); ? ? ? ? //繪制時(shí)分秒相應(yīng)的指針 ? ? ? ? float minuteDegree = minute / 60f * 360;//得到分針旋轉(zhuǎn)的角度 ? ? ? ? canvas.save(); ? ? ? ? canvas.rotate(minuteDegree, width / 2, height / 2); ? ? ? ? canvas.drawLine(width / 2, height / 2 - circleRadius + circleRadius / 3, width / 2, height / 2 + circleRadius / 6, mPaintMinute); ? ? ? ? canvas.restore(); ? ? ? ? float hourDegree = (hour * 60 + minute) / 12f / 60 * 360;//得到時(shí)鐘旋轉(zhuǎn)的角度 ? ? ? ? canvas.save(); ? ? ? ? canvas.rotate(hourDegree, width / 2, height / 2); ? ? ? ? canvas.drawLine(width / 2, height / 2 - circleRadius + circleRadius / 2, width / 2, height / 2 + circleRadius / 9, mPaintHour); ? ? ? ? canvas.restore(); ? ? ? ? float secDegree = sec / 60f * 360;//得到秒針旋轉(zhuǎn)的角度 ? ? ? ? canvas.save(); ? ? ? ? canvas.rotate(secDegree, width / 2, height / 2); ? ? ? ? canvas.drawLine(width / 2, height / 2 - circleRadius + 2, width / 2, height / 2 + circleRadius / 4, mPaintSec); ? ? ? ? canvas.restore(); ? ? } }
在布局中進(jìn)行調(diào)用
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? xmlns:tools="http://schemas.android.com/tools" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent" ? ? tools:context="com.eq.viewdemo.MainActivity"> ? ?<com.eq.viewdemo.TimeClockView ? ? ? ?android:layout_width="match_parent" ? ? ? ?android:layout_height="match_parent" ? ? ? ?android:background="#f99"/> </RelativeLayout>
到此自定義的模擬時(shí)鐘就完成了,希望對(duì)有需要的朋友起到幫助。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SwipeLayout框架實(shí)現(xiàn)側(cè)拉刪除編輯功能
這篇文章主要為大家詳細(xì)介紹了SwipeLayout框架實(shí)現(xiàn)側(cè)拉刪除編輯功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android開發(fā)基于ViewPager+GridView實(shí)現(xiàn)仿大眾點(diǎn)評(píng)橫向滑動(dòng)功能
這篇文章主要介紹了Android開發(fā)基于ViewPager+GridView實(shí)現(xiàn)仿大眾點(diǎn)評(píng)橫向滑動(dòng)功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09android仿新聞閱讀器菜單彈出效果實(shí)例(附源碼DEMO下載)
本篇文章介紹了android仿新聞閱讀器菜單彈出效果實(shí)例,現(xiàn)在很多閱讀器都有這個(gè)功能,需要的朋友可以看一下。2016-11-11Android 詳解沉浸式狀態(tài)欄的實(shí)現(xiàn)流程
沉浸式就是要給用戶提供完全沉浸的體驗(yàn),使用戶有一種置身于虛擬世界之中的感覺。沉浸式模式就是整個(gè)屏幕中顯示都是應(yīng)用的內(nèi)容,沒有狀態(tài)欄也沒有導(dǎo)航欄,用戶不會(huì)被一些系統(tǒng)的界面元素所打擾,讓我們來實(shí)現(xiàn)下網(wǎng)上傳的沸沸揚(yáng)揚(yáng)的安卓沉浸式狀態(tài)欄2021-11-11Android編程之SMS讀取短信并保存到SQLite的方法
這篇文章主要介紹了Android編程之SMS讀取短信并保存到SQLite的方法,涉及Android針對(duì)SMS短信及SQLite數(shù)據(jù)庫的相關(guān)操作技巧,需要的朋友可以參考下2015-11-11Android中自定義的dialog中的EditText無法彈出輸入法解決方案
這篇文章主要介紹了Android中自定義的dialog中的EditText無法彈出輸入法解決方案,需要的朋友可以參考下2017-04-04