Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Sample
:stuck_out_tongue_winking_eye:

![untitled](https://github.com/antonfcss/Work-with-View/assets/95831815/24ddeaff-d542-422b-8c22-10cb286eb84e)
164 changes: 164 additions & 0 deletions app/src/main/java/com/example/workwithview/CustomClockView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package com.example.workwithview

import android.R
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import java.util.Calendar
import java.util.Locale
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin

class CustomClockView(context: Context, attrs: AttributeSet? = null, defaultAttrs: Int = 1) :
View(context, attrs, defaultAttrs) {
private var height = 0
private var width = 0
private var padding = 0
private var fontSize = 0
private val numeralSpacing = 0
private var handTruncation = 0
private var hourHandTruncation = 0
private var radius = 0
private var paint: Paint? = null
private var isInit = false
private val numbers = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
private val rect = Rect()

private fun initClock() {
height = getHeight()
width = getWidth()
padding = numeralSpacing + 50
fontSize = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16f,
resources.displayMetrics
).toInt()
val min = min(height, width)
radius = min / 2 - padding
handTruncation = min / 20
hourHandTruncation = min / 7
paint = Paint()
isInit = true
}

override fun onDraw(canvas: Canvas) {
if (!isInit) {
initClock()
}
canvas.drawColor(Color.BLACK)
drawCircleOutside(canvas)
drawCircleInside(canvas)
drawCenter(canvas)
drawNumeral(canvas)
drawHands(canvas)
drawDayOfWeek(canvas)
postInvalidateDelayed(500)
invalidate()
}

private fun drawHand(canvas: Canvas, loc: Float, handType: HandType) {
val angle = Math.PI * loc / 30 - Math.PI / 2
paint!!.color = handType.color
paint!!.strokeWidth = handType.thickness
val handRadius = radius * handType.length
val x = (width / 2 + cos(angle) * handRadius).toFloat()
val y = (height / 2 + sin(angle) * handRadius).toFloat()
canvas.drawLine((width / 2).toFloat(), (height / 2).toFloat(), x, y, paint!!)
paint!!.reset()
}

private fun drawHands(canvas: Canvas) {
val calendar = Calendar.getInstance()
var hour = calendar.get(Calendar.HOUR_OF_DAY).toFloat()
hour = if (hour > 12) hour - 12 else hour
drawHand(
canvas,
((hour * 5f) + (calendar.get(Calendar.MINUTE) * 5f / 60.0)).toFloat(),
HandType.HOUR
)
drawHand(canvas, calendar.get(Calendar.MINUTE).toFloat(), HandType.MINUTE)
drawHand(canvas, calendar.get(Calendar.SECOND).toFloat(), HandType.SECOND)
}


private fun drawNumeral(canvas: Canvas) {
paint!!.textSize = fontSize.toFloat()
paint!!.color = Color.WHITE
val offset = 10
for (number in numbers) {
val tmp = number.toRoman()
paint!!.getTextBounds(tmp, 0, tmp.length, rect)
val angle = Math.PI / 6 * (number - 3)
val x = (width / 2 + cos(angle) * (radius + offset) - rect.width() / 2).toInt()
val y = (height / 2 + sin(angle) * (radius + offset) + rect.height() / 2).toInt()
canvas.drawText(tmp, x.toFloat(), y.toFloat(), paint!!)
}
}

private fun drawCenter(canvas: Canvas) {
paint!!.style = Paint.Style.FILL
canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), 7f, paint!!)
}

private fun drawCircleOutside(canvas: Canvas) {
paint!!.reset()
paint!!.color = resources.getColor(R.color.white)
paint!!.strokeWidth = 5f
paint!!.style = Paint.Style.STROKE
paint!!.isAntiAlias = true
canvas.drawCircle(
(width / 2).toFloat(), (height / 2).toFloat(), (radius + padding - 10).toFloat(),
paint!!
)
}

private fun drawCircleInside(canvas: Canvas) {
paint!!.reset()
paint!!.color = resources.getColor(R.color.white)
paint!!.strokeWidth = 1f
paint!!.style = Paint.Style.STROKE
paint!!.isAntiAlias = true
canvas.drawCircle(
(width / 2).toFloat(), (height / 2).toFloat(), (radius + padding - 70).toFloat(),
paint!!
)
}
private fun drawDayOfWeek(canvas: Canvas) {
val calendar = Calendar.getInstance()
val dayOfWeek =
calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault())
paint!!.textSize = fontSize.toFloat() * 1.5f
paint!!.color = Color.WHITE
val textBounds = Rect()
paint!!.getTextBounds(dayOfWeek, 0, dayOfWeek.length, textBounds)
canvas.drawText(
dayOfWeek,
(width - textBounds.width()) / 2f,
(height / 10).toFloat(),
paint!!
)
}

fun Int.toRoman(): String {
val romanNumbersArray = arrayOfNulls<String>(13)
romanNumbersArray[0] = ""
romanNumbersArray[1] = "I"
romanNumbersArray[2] = "II"
romanNumbersArray[3] = "III"
romanNumbersArray[4] = "IV"
romanNumbersArray[5] = "V"
romanNumbersArray[6] = "VI"
romanNumbersArray[7] = "VII"
romanNumbersArray[8] = "VIII"
romanNumbersArray[9] = "IX"
romanNumbersArray[10] = "X"
romanNumbersArray[11] = "XI"
romanNumbersArray[12] = "XII"
return romanNumbersArray[this]!!
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/com/example/workwithview/HandType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.workwithview

import android.graphics.Color

enum class HandType(val color: Int, val thickness: Float, val length: Float) {
HOUR(Color.RED, 9f, 0.5f),
MINUTE(Color.WHITE, 5f, 0.7f),
SECOND(Color.WHITE, 3f, 0.8f)
}
6 changes: 3 additions & 3 deletions app/src/main/java/com/example/workwithview/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.example.workwithview

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setContentView(CustomClockView(this))
}
}
}