From 523bac7f8a0c75ff945cededab1b6d9bf871bc61 Mon Sep 17 00:00:00 2001 From: Raymond Yang Date: Sat, 8 Apr 2023 13:01:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E6=8C=87=E9=87=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ray650128/iosclockwidget/IOSClockView.kt | 177 +++++++++++++++--- app/src/main/res/layout/activity_main.xml | 9 +- .../main/res/layout/i_o_s_clock_widget.xml | 18 +- 3 files changed, 175 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/ray650128/iosclockwidget/IOSClockView.kt b/app/src/main/java/com/ray650128/iosclockwidget/IOSClockView.kt index db544a8..d1b3095 100644 --- a/app/src/main/java/com/ray650128/iosclockwidget/IOSClockView.kt +++ b/app/src/main/java/com/ray650128/iosclockwidget/IOSClockView.kt @@ -4,6 +4,7 @@ import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.View +import java.util.* import kotlin.math.cos import kotlin.math.sin @@ -35,7 +36,7 @@ class IOSClockView: View { Paint().apply { isAntiAlias = true style = Paint.Style.FILL - color = Color.BLACK + color = Color.parseColor("#101010") } } @@ -47,12 +48,21 @@ class IOSClockView: View { } } - private val clockScale: Paint by lazy { + private val clockHourScale: Paint by lazy { Paint().apply { isAntiAlias = true style = Paint.Style.STROKE - color = Color.DKGRAY - width = 2 + color = Color.BLACK + strokeWidth = this@IOSClockView.width * 0.005f + } + } + + private val clockMinuteScale: Paint by lazy { + Paint().apply { + isAntiAlias = true + style = Paint.Style.STROKE + color = Color.GRAY + strokeWidth = this@IOSClockView.width * 0.005f } } @@ -91,7 +101,9 @@ class IOSClockView: View { drawClockFace(canvas) - drawScaleArc(canvas) + drawScaleHourHand(canvas, 12) + + postInvalidateDelayed(100) } private fun drawClockFace(canvas: Canvas?) { @@ -100,32 +112,149 @@ class IOSClockView: View { it.drawRoundRect(bgRectF, width / 7f, width / 7f, background) it.drawOval(clockFaceRectF, clockFace) + + drawScaleMinute(it) + + drawScaleHour(it) } } - private fun drawScaleArc(canvas: Canvas?) { + private fun drawScaleMinute(canvas: Canvas?) { // 360 * Math.PI / 180 - val evenryDegrees = (2.0f * Math.PI / 60).toFloat() - - val startDegress = (150 * Math.PI / 180).toFloat() - val endDegress = (210 * Math.PI / 180).toFloat() + val everyDegrees = (6f * Math.PI / 180).toFloat() for (i in 0 until 60) { - val degrees = i * evenryDegrees - // 過濾底部60度的弧長 - if (degrees > startDegress && degrees < endDegress) { - continue - } - - val startX = centerX + sin(degrees.toDouble()).toFloat() * (radius * 0.8f) - val startY = centerY - cos(degrees.toDouble()).toFloat() * (radius * 0.8f) - - val stopX = centerX + sin(degrees.toDouble()).toFloat() * (radius * 0.85f) - - val stopY = centerY - cos(degrees.toDouble()).toFloat() * (radius * 0.85f) - - canvas?.drawLine(startX, startY, stopX, stopY, clockScale) + val degrees = i * everyDegrees + val startX = centerX + sin(degrees.toDouble()).toFloat() * (radius * 0.875f) + val startY = centerY - cos(degrees.toDouble()).toFloat() * (radius * 0.875f) + val stopX = centerX + sin(degrees.toDouble()).toFloat() * (radius * 0.95f) + val stopY = centerY - cos(degrees.toDouble()).toFloat() * (radius * 0.95f) + canvas?.drawLine(startX, startY, stopX, stopY, clockMinuteScale) } } + private fun drawScaleHour(canvas: Canvas?) { + // 360 * Math.PI / 180 + val everyDegrees = (30f * Math.PI / 180).toFloat() + + for (i in 0 until 60) { + val degrees = i * everyDegrees + val startX = centerX + sin(degrees.toDouble()).toFloat() * (radius * 0.875f) + val startY = centerY - cos(degrees.toDouble()).toFloat() * (radius * 0.875f) + val stopX = centerX + sin(degrees.toDouble()).toFloat() * (radius * 0.95f) + val stopY = centerY - cos(degrees.toDouble()).toFloat() * (radius * 0.95f) + canvas?.drawLine(startX, startY, stopX, stopY, clockHourScale) + } + } + + private fun drawScaleHourHand(canvas: Canvas?, value: Int) { + val mPaint = Paint() + val mPointRange = 100f + // 取得目前時間:時、分、秒 + val calendar = Calendar.getInstance() + val hour = calendar[Calendar.HOUR] + val minute = calendar[Calendar.MINUTE] + val second = calendar[Calendar.SECOND] + // 計算時、分、秒的旋轉角度 + val angleHour = (hour + minute.toFloat() / 60) * 360 / 12 + val angleMinute = (minute + second.toFloat() / 60) * 360 / 60 + val angleSecond = second * 360 / 60 + + //region 繪製時針 + canvas?.save() + // 旋轉到時針的角度 + canvas?.rotate(angleHour, centerX, centerY) + // 繪製時針1 + val rectHour = RectF( + centerX - 10f / 2, + centerY - radius / 2, + centerX + 10f / 2, + centerY - radius / 6 + ) + // 設定時針畫筆屬性 + mPaint.color = Color.BLACK + mPaint.style = Paint.Style.STROKE + mPaint.strokeWidth = 10f + canvas?.drawRoundRect(rectHour, mPointRange, mPointRange, mPaint) + + // 繪製時針2 + val rectHour2 = RectF( + centerX - 10f / 2, + centerY - radius / 2, + centerX + 10f / 2, + centerY + ) + // 設定時針畫筆屬性 + mPaint.color = Color.BLACK + mPaint.style = Paint.Style.FILL + mPaint.strokeWidth = 5f + canvas?.drawRoundRect(rectHour2, mPointRange, mPointRange, mPaint) + canvas?.restore() + //endregion + + //region 繪製分針 + // 繪製分針 + canvas?.save() + // 旋轉到分針的角度 + canvas?.rotate(angleMinute, centerX, centerY) + val rectMinute = RectF( + centerX - 10f / 2, + centerY - radius * 3.5f / 5, + centerX + 10f / 2, + centerY - radius / 6 + ) + // 設定分針畫筆屬性 + mPaint.color = Color.BLACK + mPaint.style = Paint.Style.STROKE + mPaint.strokeWidth = 10f + canvas?.drawRoundRect(rectMinute, mPointRange, mPointRange, mPaint) + + val rectMinute2 = RectF( + centerX - 10f / 2, + centerY - radius * 3.5f / 5, + centerX + 10f / 2, + centerY + ) + // 設定分針畫筆屬性 + mPaint.color = Color.BLACK + mPaint.style = Paint.Style.FILL + mPaint.strokeWidth = 5f + canvas?.drawRoundRect(rectMinute2, mPointRange, mPointRange, mPaint) + canvas?.restore() + //endregion + + // 繪製時、分針原點 + mPaint.style = Paint.Style.FILL + mPaint.color = Color.BLACK + canvas?.drawCircle(centerX, centerY, 5f * 4, mPaint) + + // 繪製秒針 + canvas?.save() + // 旋轉到分針的角度 + canvas?.rotate(angleSecond.toFloat(), centerX, centerY) + val rectSecond = RectF( + centerX - 5f / 2, + centerY - radius + 20, + centerX + 5f / 2, + centerY + radius / 6 + ) + // 設定秒針畫筆屬性 + mPaint.strokeWidth = 5f + mPaint.style = Paint.Style.STROKE + mPaint.color = Color.parseColor("#FF7F27") + canvas?.drawRoundRect(rectSecond, mPointRange, mPointRange, mPaint) + canvas?.restore() + + // 繪製秒針原點白底 + mPaint.style = Paint.Style.FILL + mPaint.color = Color.WHITE + canvas?.drawCircle(centerX, centerY, 2.5f * 4, mPaint) + + // 繪製秒針原點外框 + mPaint.style = Paint.Style.STROKE + mPaint.color = Color.parseColor("#FF7F27") + mPaint.strokeWidth = 5f + canvas?.drawCircle(centerX, centerY, 2.5f * 4, mPaint) + } + } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 17eab17..a469333 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,11 +6,12 @@ android:layout_height="match_parent" tools:context=".MainActivity"> - diff --git a/app/src/main/res/layout/i_o_s_clock_widget.xml b/app/src/main/res/layout/i_o_s_clock_widget.xml index 439790c..b15145b 100644 --- a/app/src/main/res/layout/i_o_s_clock_widget.xml +++ b/app/src/main/res/layout/i_o_s_clock_widget.xml @@ -3,4 +3,20 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" - android:theme="@style/Theme.IOSClockWidget.AppWidgetContainer"/> \ No newline at end of file + android:theme="@style/Theme.IOSClockWidget.AppWidgetContainer"> + + + + + \ No newline at end of file