Compare commits
13
Commits
822d6fc1b1
...
b30427d862
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b30427d862 | ||
|
|
eaaeb7fa35 | ||
|
|
6ba2f2cfdf | ||
|
|
51c7fa1464 | ||
|
|
df9d92f116 | ||
|
|
5b517f39d6 | ||
|
|
b20208fb40 | ||
|
|
9b733f2102 | ||
|
|
0738fc466e | ||
|
|
7491083e6a | ||
|
|
13786f6c8e | ||
|
|
92952a2cf2 | ||
|
|
6de400753c |
@@ -24,12 +24,12 @@ class CountdownCanvasView @JvmOverloads constructor(
|
|||||||
isFakeBoldText = false
|
isFakeBoldText = false
|
||||||
}
|
}
|
||||||
private val ringPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
private val ringPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
color = Color.parseColor("#6750A4")
|
color = ContextCompat.getColor(context, R.color.md_color_ring_progress)
|
||||||
style = Paint.Style.STROKE
|
style = Paint.Style.STROKE
|
||||||
strokeWidth = 16f
|
strokeWidth = 16f
|
||||||
}
|
}
|
||||||
private val ringBgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
private val ringBgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
color = Color.parseColor("#D0BCFF")
|
color = ContextCompat.getColor(context, R.color.md_color_ring_track)
|
||||||
style = Paint.Style.STROKE
|
style = Paint.Style.STROKE
|
||||||
strokeWidth = 16f
|
strokeWidth = 16f
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class CountdownDialog(
|
|||||||
private val prefs: SharedPreferences
|
private val prefs: SharedPreferences
|
||||||
) : Dialog(context) {
|
) : Dialog(context) {
|
||||||
private lateinit var cvCountdown: CountdownCanvasView
|
private lateinit var cvCountdown: CountdownCanvasView
|
||||||
private lateinit var btnStop: Button
|
private lateinit var btnStop: View
|
||||||
private lateinit var btnRestart: Button
|
private lateinit var btnRestart: View
|
||||||
private lateinit var btnDismiss: Button
|
private lateinit var btnDismiss: Button
|
||||||
private var timer: CountDownTimer? = null
|
private var timer: CountDownTimer? = null
|
||||||
private var toneGenerator: ToneGenerator? = null
|
private var toneGenerator: ToneGenerator? = null
|
||||||
@@ -61,14 +61,10 @@ class CountdownDialog(
|
|||||||
val progress = millisUntilFinished.toFloat() / durationMillis
|
val progress = millisUntilFinished.toFloat() / durationMillis
|
||||||
cvCountdown.setProgress(progress)
|
cvCountdown.setProgress(progress)
|
||||||
|
|
||||||
if (millisUntilFinished >= durationMillis) {
|
val secondsLeft = (millisUntilFinished / 1000).toInt() + 1
|
||||||
cvCountdown.setText(context.getString(R.string.countdown_text))
|
cvCountdown.setText(secondsLeft.toString())
|
||||||
} else {
|
|
||||||
val secondsLeft = (millisUntilFinished / 1000).toInt() + 1
|
|
||||||
cvCountdown.setText(secondsLeft.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (millisUntilFinished <= 3000 && millisUntilFinished > 1000) {
|
if (secondsLeft >= 1 && secondsLeft <= 3) {
|
||||||
playTone(ToneGenerator.TONE_PROP_BEEP)
|
playTone(ToneGenerator.TONE_PROP_BEEP)
|
||||||
if (prefs.getBoolean("vibration", true)) {
|
if (prefs.getBoolean("vibration", true)) {
|
||||||
vibrator?.vibrate(50)
|
vibrator?.vibrate(50)
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_checked="true" android:color="#81C784" />
|
||||||
|
<item android:color="#E8E8E8" />
|
||||||
|
</selector>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="40dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#81C784"
|
||||||
|
android:endColor="#4CAF50"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#A5D6A7" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="40dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#C8E6C9"
|
||||||
|
android:endColor="#A5D6A7"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#E8F5E9" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="40dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#66BB6A"
|
||||||
|
android:endColor="#388E3C"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#81C784" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/btn_duration_disabled" android:state_enabled="false" />
|
||||||
|
<item android:drawable="@drawable/btn_duration_pressed" android:state_pressed="true" />
|
||||||
|
<item android:drawable="@drawable/btn_duration_pressed" android:state_activated="true" />
|
||||||
|
<item android:drawable="@drawable/btn_duration_default" />
|
||||||
|
</selector>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#42A5F5"
|
||||||
|
android:endColor="#1565C0"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#90CAF9" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#90CAF9"
|
||||||
|
android:endColor="#64B5F6"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#BBDEFB" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#1E88E5"
|
||||||
|
android:endColor="#0D47A1"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#42A5F5" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/btn_restart_disabled" android:state_enabled="false" />
|
||||||
|
<item android:drawable="@drawable/btn_restart_pressed" android:state_pressed="true" />
|
||||||
|
<item android:drawable="@drawable/btn_restart_pressed" android:state_activated="true" />
|
||||||
|
<item android:drawable="@drawable/btn_restart_default" />
|
||||||
|
</selector>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#4CAF50"
|
||||||
|
android:endColor="#2E7D32"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#66BB6A" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#A5D6A7"
|
||||||
|
android:endColor="#81C784"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#C8E6C9" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#388E3C"
|
||||||
|
android:endColor="#1B5E20"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#4CAF50" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/btn_start_disabled" android:state_enabled="false" />
|
||||||
|
<item android:drawable="@drawable/btn_start_pressed" android:state_pressed="true" />
|
||||||
|
<item android:drawable="@drawable/btn_start_pressed" android:state_activated="true" />
|
||||||
|
<item android:drawable="@drawable/btn_start_default" />
|
||||||
|
</selector>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#EF5350"
|
||||||
|
android:endColor="#C62828"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#EF9A9A" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#EF9A9A"
|
||||||
|
android:endColor="#E57373"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#FFCDD2" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="120dp" android:height="120dp" />
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="#E53935"
|
||||||
|
android:endColor="#B71C1C"
|
||||||
|
android:type="linear" />
|
||||||
|
<stroke
|
||||||
|
android:width="3dp"
|
||||||
|
android:color="#EF5350" />
|
||||||
|
</shape>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/btn_stop_disabled" android:state_enabled="false" />
|
||||||
|
<item android:drawable="@drawable/btn_stop_pressed" android:state_pressed="true" />
|
||||||
|
<item android:drawable="@drawable/btn_stop_pressed" android:state_activated="true" />
|
||||||
|
<item android:drawable="@drawable/btn_stop_default" />
|
||||||
|
</selector>
|
||||||
@@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#6750A4"
|
android:fillColor="#FFFFFF"
|
||||||
android:pathData="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6z"/>
|
android:pathData="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="48dp"
|
||||||
|
android:height="48dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4L17.65,6.35z"
|
||||||
|
android:strokeWidth="0" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="48dp"
|
||||||
|
android:height="48dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M6,6h12v12H6z"
|
||||||
|
android:strokeWidth="0" />
|
||||||
|
</vector>
|
||||||
@@ -110,15 +110,22 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<Button
|
||||||
android:id="@+id/btnDurationLabel"
|
android:id="@+id/btnDurationLabel"
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
android:layout_width="180dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="80dp"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="32dp"
|
android:layout_marginTop="32dp"
|
||||||
|
android:background="@drawable/btn_duration_selector"
|
||||||
android:text="@string/start_timer"
|
android:text="@string/start_timer"
|
||||||
android:drawableEnd="@drawable/ic_keyboard_arrow_down"
|
android:drawableEnd="@drawable/ic_keyboard_arrow_down"
|
||||||
app:cornerRadius="20dp" />
|
android:drawablePadding="8dp"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:includeFontPadding="false" />
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
android:id="@+id/hsvDurationOptions"
|
android:id="@+id/hsvDurationOptions"
|
||||||
@@ -139,6 +146,8 @@
|
|||||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="56dp"
|
||||||
|
app:chipBackgroundColor="@color/chip_duration_bg"
|
||||||
android:text="5s" />
|
android:text="5s" />
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
@@ -146,7 +155,9 @@
|
|||||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="56dp"
|
||||||
android:checked="true"
|
android:checked="true"
|
||||||
|
app:chipBackgroundColor="@color/chip_duration_bg"
|
||||||
android:text="10s" />
|
android:text="10s" />
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
@@ -154,6 +165,8 @@
|
|||||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="56dp"
|
||||||
|
app:chipBackgroundColor="@color/chip_duration_bg"
|
||||||
android:text="15s" />
|
android:text="15s" />
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
@@ -161,19 +174,25 @@
|
|||||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
style="@style/Widget.Material3.Chip.Suggestion.Elevated"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="56dp"
|
||||||
|
app:chipBackgroundColor="@color/chip_duration_bg"
|
||||||
android:text="30s" />
|
android:text="30s" />
|
||||||
</com.google.android.material.chip.ChipGroup>
|
</com.google.android.material.chip.ChipGroup>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<Button
|
||||||
android:id="@+id/btnStart"
|
android:id="@+id/btnStart"
|
||||||
style="@style/Widget.Material3.Button"
|
android:layout_width="120dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="120dp"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/btn_start_selector"
|
||||||
|
android:drawableTop="@drawable/ic_play_arrow"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
android:text="@string/start_timer"
|
android:text="@string/start_timer"
|
||||||
app:cornerRadius="20dp"
|
android:textColor="#FFFFFF"
|
||||||
app:icon="@drawable/ic_play_arrow" />
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|||||||
@@ -5,47 +5,79 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#80000000">
|
android:background="#80000000">
|
||||||
|
|
||||||
|
<com.example.countdowntimer.CountdownCanvasView
|
||||||
|
android:id="@+id/cvCountdown"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/buttonRow"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/buttonRow"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="48dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/btnStop"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:background="@drawable/btn_stop_selector"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:contentDescription="@string/stop_timer"
|
||||||
|
android:src="@drawable/ic_stop_square" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/btnRestart"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:background="@drawable/btn_restart_selector"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:contentDescription="@string/restart_timer"
|
||||||
|
android:src="@drawable/ic_refresh_square" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnDismiss"
|
android:id="@+id/btnDismiss"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="100dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="100dp"
|
||||||
|
android:background="@drawable/btn_duration_selector"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="16dp"
|
||||||
android:text="Dismiss"
|
android:text="Dismiss"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<com.example.countdowntimer.CountdownCanvasView
|
|
||||||
android:id="@+id/cvCountdown"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/btnStop"
|
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
android:layout_margin="16dp" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnStop"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Stop"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/btnRestart"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnRestart"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Restart"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/btnStop"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -2,4 +2,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="color_gradient_start">#1B3A1B</color>
|
<color name="color_gradient_start">#1B3A1B</color>
|
||||||
<color name="color_gradient_end">#0D1F0D</color>
|
<color name="color_gradient_end">#0D1F0D</color>
|
||||||
|
<color name="md_color_ring_progress">#A5D6A7</color>
|
||||||
|
<color name="md_color_ring_track">#2E7D32</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="md_theme_dark_primary">#A5D6A7</color>
|
<color name="md_theme_dark_primary">#A5D6A7</color>
|
||||||
|
<color name="md_theme_dark_primaryContainer">#2E7D32</color>
|
||||||
<color name="md_theme_dark_secondary">#869F7C</color>
|
<color name="md_theme_dark_secondary">#869F7C</color>
|
||||||
|
|
||||||
<style name="Theme.CountdownTimer" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="Theme.CountdownTimer" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
|||||||
@@ -3,4 +3,6 @@
|
|||||||
<color name="color_gradient_start">#E8F5E9</color>
|
<color name="color_gradient_start">#E8F5E9</color>
|
||||||
<color name="color_gradient_end">#C8E6C9</color>
|
<color name="color_gradient_end">#C8E6C9</color>
|
||||||
<color name="color_icon_tint">#2E7D32</color>
|
<color name="color_icon_tint">#2E7D32</color>
|
||||||
|
<color name="md_color_ring_progress">#2E7D32</color>
|
||||||
|
<color name="md_color_ring_track">#81C784</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -11,4 +11,6 @@
|
|||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="vibration">Vibration</string>
|
<string name="vibration">Vibration</string>
|
||||||
<string name="sounds">Sounds</string>
|
<string name="sounds">Sounds</string>
|
||||||
|
<string name="stop_timer">Stop Timer</string>
|
||||||
|
<string name="restart_timer">Restart Timer</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<style name="Theme.CountdownTimer" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="Theme.CountdownTimer" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
<item name="colorPrimary">@color/md_theme_light_primary</item>
|
<item name="colorPrimary">@color/md_theme_light_primary</item>
|
||||||
|
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
|
||||||
<item name="colorSecondary">@color/md_theme_light_secondary</item>
|
<item name="colorSecondary">@color/md_theme_light_secondary</item>
|
||||||
<item name="android:statusBarColor">@color/color_gradient_start</item>
|
<item name="android:statusBarColor">@color/color_gradient_start</item>
|
||||||
<item name="android:windowLightStatusBar">true</item>
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<color name="md_theme_light_primary">#2E7D32</color>
|
<color name="md_theme_light_primary">#2E7D32</color>
|
||||||
|
<color name="md_theme_light_primaryContainer">#81C784</color>
|
||||||
<color name="md_theme_light_secondary">#4C6842</color>
|
<color name="md_theme_light_secondary">#4C6842</color>
|
||||||
<color name="md_theme_light_surface">#F1F8E9</color>
|
<color name="md_theme_light_surface">#F1F8E9</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# Goal: Redesign all buttons into bold, square, visually striking interactive elements
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
Replace every basic/rectangular button in the app with larger, square-aspect-ratio buttons that have eye-catching visual design. The goal is to transform the UI from a generic Material 3 look into a distinctive, personality-rich interface that matches the playful "BONG HIT TIMER" brand.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
The app uses 4 visible buttons across 2 screens:
|
||||||
|
|
||||||
|
**MainActivity (home screen):**
|
||||||
|
- `btnDurationLabel` — outlined button showing selected duration (e.g. "10s") with a dropdown arrow. Uses `Widget.Material3.Button.OutlinedButton` with 20dp corners.
|
||||||
|
- `btnStart` — filled button labeled "Start Timer" with a play icon. Uses `Widget.Material3.Button` with 20dp corners.
|
||||||
|
|
||||||
|
**CountdownDialog (timer screen):**
|
||||||
|
- `btnStop` — plain Android `Button` labeled "Stop" (default styling, small)
|
||||||
|
- `btnRestart` — plain Android `Button` labeled "Restart" (default styling, small)
|
||||||
|
- `btnDismiss` — plain Android `Button` labeled "Dismiss" (currently gone, shows after timer completes)
|
||||||
|
|
||||||
|
## Design Requirements
|
||||||
|
|
||||||
|
### 1. Square Aspect Ratio
|
||||||
|
- Change all buttons from `wrap_content` rectangles to a fixed square size (e.g., `120dp` x `120dp` or `100dp` x `100dp`)
|
||||||
|
- Use `app:layout_constraintDimensionRatio="1:1"` where dynamic sizing is needed
|
||||||
|
- Buttons should feel substantial and tappable, not compact
|
||||||
|
|
||||||
|
### 2. Visual Interest — Each button should have its own personality
|
||||||
|
Create custom drawable backgrounds for each button type. Design ideas (pick the best approach):
|
||||||
|
|
||||||
|
- **Circular/spherical buttons** — Buttons that look like physical 3D balls or pucks. Use gradient fills with highlights/shadows to create a convex "pressable" look.
|
||||||
|
- **Neon/glow effect** — Since the app is a bong hit timer, a subtle neon glow that pulses or intensifies during countdown would be thematically appropriate.
|
||||||
|
- **Retro/gaming arcade style** — Bold colors, thick borders, pressed/active states that simulate physical button depression.
|
||||||
|
- **Gradient + icon centering** — For the timer screen, center the stop/restart icons prominently in the square buttons with bold gradient backgrounds.
|
||||||
|
|
||||||
|
### 3. Interactive States
|
||||||
|
Every button must have rich feedback:
|
||||||
|
- **Pressed/active state** — noticeable visual change (shrink, darker shade, or inner glow)
|
||||||
|
- **Default state** — visually engaging with gradients, shadows, or subtle animations
|
||||||
|
- **Disabled state** — reduced opacity but still recognizable
|
||||||
|
|
||||||
|
### 4. Icon Integration
|
||||||
|
Square buttons are perfect for icon-first design:
|
||||||
|
- **Stop button** — large centered pause/stop icon
|
||||||
|
- **Restart button** — large centered refresh/replay icon
|
||||||
|
- **Start button** — center the play icon, consider removing the text label since the icon is universal
|
||||||
|
- **Duration label** — consider a pill-shaped or circular chip that pulses when tapped
|
||||||
|
|
||||||
|
### 5. Color Palette
|
||||||
|
Stay within the existing green theme (`#2E7D32` primary, `#4C6842` secondary, `#E8F5E9`/`#C8E6C9` gradient) but push it further:
|
||||||
|
- Use the primary green for the start/positive actions
|
||||||
|
- A red/coral accent for stop
|
||||||
|
- A neutral or blue for restart/duration selection
|
||||||
|
- Consider gradient transitions within each button (e.g., green to darker green top-to-bottom for a 3D effect)
|
||||||
|
|
||||||
|
### 6. Shadow & Elevation
|
||||||
|
- Add drop shadows to all buttons for depth (use `app:strokeWidth="0dp"` and custom `rippleColor` for Material buttons)
|
||||||
|
- Create a `btn_square_default.xml` and `btn_square_pressed.xml` in `res/drawable/` for each button type
|
||||||
|
- The pressed state should visually simulate "pressing in" (reduced shadow, lighter/darker fill)
|
||||||
|
|
||||||
|
## Technical Implementation
|
||||||
|
|
||||||
|
### New drawable files to create (in `res/drawable/`):
|
||||||
|
- `btn_start_square.xml` — gradient + shadow drawable for start button
|
||||||
|
- `btn_start_square_pressed.xml` — pressed state variant
|
||||||
|
- `btn_stop_square.xml` — gradient + shadow drawable for stop button
|
||||||
|
- `btn_stop_square_pressed.xml` — pressed state variant
|
||||||
|
- `btn_restart_square.xml` — gradient + shadow drawable for restart button
|
||||||
|
- `btn_restart_square_pressed.xml` — pressed state variant
|
||||||
|
- `btn_duration_chip.xml` — drawable for duration selector
|
||||||
|
|
||||||
|
### Layout changes needed:
|
||||||
|
- `activity_main.xml`:
|
||||||
|
- `btnDurationLabel`: change to square dimensions, wrap text/icon in center, apply new drawable
|
||||||
|
- `btnStart`: change to square, center play icon, apply new drawable
|
||||||
|
- `dialog_countdown.xml`:
|
||||||
|
- `btnStop`: change from `Button` to `com.google.android.material.button.MaterialButton`, set square dimensions, apply drawable
|
||||||
|
- `btnRestart`: same treatment
|
||||||
|
- `btnDismiss`: same treatment, keep as gone by default
|
||||||
|
- Adjust the ConstraintLayout chain to accommodate square buttons (may need a horizontal chain with proper spacing)
|
||||||
|
|
||||||
|
### Code changes needed:
|
||||||
|
- `CountdownDialog.kt`: Set button backgrounds programmatically if needed, ensure clickable/pressable states work
|
||||||
|
- No changes to button click logic — only visual overhaul
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
- Use only Material 3 components already in the dependency (`com.google.android.material:material:1.11.0`)
|
||||||
|
- Traditional XML layouts — no Compose
|
||||||
|
- Minimum SDK 24 — no API 30+ features
|
||||||
|
- Keep the app's existing green aesthetic but make it bolder
|
||||||
|
- Maintain accessibility (minimum 48dp touch target, sufficient contrast)
|
||||||
Reference in New Issue
Block a user