Implement concise view for timer

- implement EditTimerDialog
- adding a new timer would show the dialog
- clicking on a timer item would show the dialog
This commit is contained in:
Paul Akhamiogu 2021-09-07 15:24:21 +01:00
parent bd05a41b35
commit e1357ecd8f
10 changed files with 330 additions and 239 deletions

View File

@ -1,8 +1,6 @@
package com.simplemobiletools.clock.adapters
import android.graphics.Color
import android.media.AudioManager
import android.media.RingtoneManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -13,19 +11,17 @@ import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.SimpleActivity
import com.simplemobiletools.clock.dialogs.MyTimePickerDialogDialog
import com.simplemobiletools.clock.extensions.*
import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID
import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.clock.models.TimerEvent
import com.simplemobiletools.clock.models.TimerState
import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.models.AlarmSound
import kotlinx.android.synthetic.main.item_timer.view.*
import org.greenrobot.eventbus.EventBus
class TimerAdapter(
private val activity: SimpleActivity,
private val onRefresh: () -> Unit,
private val onClick: (Timer) -> Unit,
) : ListAdapter<Timer, TimerAdapter.TimerViewHolder>(diffUtil) {
companion object {
@ -42,12 +38,7 @@ class TimerAdapter(
private val config = activity.config
private var textColor = config.textColor
private var primaryColor = config.primaryColor
private var adjustedPrimaryColor = activity.getAdjustedPrimaryColor()
private var contrastColor = adjustedPrimaryColor.getContrastColor()
private var backgroundColor = config.backgroundColor
private var selectedTimer: Timer? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimerViewHolder {
return TimerViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_timer, parent, false))
@ -62,29 +53,11 @@ class TimerAdapter(
onRefresh.invoke()
}
fun updatePrimaryColor(primaryColor: Int) {
this.primaryColor = primaryColor
adjustedPrimaryColor = activity.getAdjustedPrimaryColor()
contrastColor = adjustedPrimaryColor.getContrastColor()
onRefresh.invoke()
}
inner class TimerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
itemView.timer_label.onTextChangeListener { text ->
updateTimer(getItem(adapterPosition).copy(label = text), false)
}
}
fun bind(timer: Timer) {
itemView.apply {
post {
timer_initial_time.colorLeftDrawable(textColor)
timer_vibrate.colorLeftDrawable(textColor)
timer_label_image.applyColorFilter(textColor)
timer_sound.colorLeftDrawable(textColor)
timer_play_pause.background = activity.resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, adjustedPrimaryColor)
timer_play_pause.applyColorFilter(if (adjustedPrimaryColor == Color.WHITE) Color.BLACK else Color.WHITE)
timer_reset.applyColorFilter(textColor)
@ -97,16 +70,6 @@ class TimerAdapter(
timer_label.setText(timer.label)
}
timer_initial_time.text = timer.seconds.getFormattedDuration()
timer_initial_time.setTextColor(textColor)
timer_vibrate.isChecked = timer.vibrate
timer_vibrate.setTextColor(textColor)
timer_vibrate.setColors(textColor, adjustedPrimaryColor, backgroundColor)
timer_vibrate_holder.setOnClickListener {
timer_vibrate.toggle()
updateTimer(timer.copy(vibrate = timer_vibrate.isChecked, channelId = null), false)
}
timer_time.setTextColor(textColor)
timer_time.text = when (timer.state) {
@ -119,33 +82,6 @@ class TimerAdapter(
changeDuration(timer)
}
timer_initial_time.setTextColor(textColor)
timer_initial_time.setOnClickListener {
changeDuration(timer)
}
timer_sound.text = timer.soundTitle
timer_sound.setTextColor(textColor)
timer_sound.setOnClickListener {
selectedTimer = timer
SelectAlarmSoundDialog(activity, timer.soundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID,
RingtoneManager.TYPE_ALARM, true,
onAlarmPicked = { sound ->
if (sound != null) {
updateAlarmSound(timer, sound)
}
},
onAlarmSoundDeleted = { sound ->
if (timer.soundUri == sound.uri) {
val defaultAlarm = context.getDefaultAlarmSound(RingtoneManager.TYPE_ALARM)
updateAlarmSound(timer, defaultAlarm)
}
context.checkAlarmsWithDeletedSoundUri(sound.uri)
})
}
timer_delete.applyColorFilter(textColor)
timer_delete.setOnClickListener {
activity.timerHelper.deleteTimer(timer.id!!) {
@ -167,7 +103,12 @@ class TimerAdapter(
is TimerState.Finished -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
}
}
updateViewStates(timer.state)
setOnClickListener {
onClick.invoke(timer)
}
}
}
@ -188,14 +129,6 @@ class TimerAdapter(
}
}
fun updateAlarmSoundForSelectedTimer(alarmSound: AlarmSound) {
selectedTimer?.let { updateAlarmSound(it, alarmSound) }
}
fun updateAlarmSound(timer: Timer, alarmSound: AlarmSound) {
updateTimer(timer.copy(soundTitle = alarmSound.title, soundUri = alarmSound.uri, channelId = null))
}
private fun updateTimer(timer: Timer, refresh: Boolean = true) {
activity.timerHelper.insertOrUpdateTimer(timer) {
if (refresh) {

View File

@ -0,0 +1,115 @@
package com.simplemobiletools.clock.dialogs
import android.media.AudioManager
import android.media.RingtoneManager
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.SimpleActivity
import com.simplemobiletools.clock.extensions.*
import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID
import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.models.AlarmSound
import kotlinx.android.synthetic.main.dialog_edit_timer.view.*
class EditTimerDialog(val activity: SimpleActivity, val timer: Timer, val callback: () -> Unit) {
private val view = activity.layoutInflater.inflate(R.layout.dialog_edit_timer, null)
private val textColor = activity.config.textColor
init {
restoreLastAlarm()
updateAlarmTime()
view.apply {
edit_timer_initial_time.text = timer.seconds.getFormattedDuration()
edit_timer_initial_time.setTextColor(textColor)
edit_timer_initial_time.setOnClickListener {
changeDuration(timer)
}
edit_timer_vibrate.colorLeftDrawable(textColor)
edit_timer_vibrate.isChecked = timer.vibrate
edit_timer_vibrate.setTextColor(textColor)
edit_timer_vibrate_holder.setOnClickListener {
edit_timer_vibrate.toggle()
timer.vibrate = edit_timer_vibrate.isChecked
timer.channelId = null
}
edit_timer_sound.colorLeftDrawable(textColor)
edit_timer_sound.text = timer.soundTitle
edit_timer_sound.setOnClickListener {
SelectAlarmSoundDialog(activity, timer.soundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID,
RingtoneManager.TYPE_ALARM, true,
onAlarmPicked = { sound ->
if (sound != null) {
updateAlarmSound(sound)
}
},
onAlarmSoundDeleted = { sound ->
if (timer.soundUri == sound.uri) {
val defaultAlarm = context.getDefaultAlarmSound(RingtoneManager.TYPE_ALARM)
updateAlarmSound(defaultAlarm)
}
context.checkAlarmsWithDeletedSoundUri(sound.uri)
})
}
edit_timer_label_image.applyColorFilter(textColor)
edit_timer_label.setText(timer.label)
}
AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this) {
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
timer.label = view.edit_timer_label.value
activity.timerHelper.insertOrUpdateTimer(timer){
activity.config.timerLastConfig = timer
callback()
dismiss()
}
}
}
}
}
private fun restoreLastAlarm() {
if (timer.id == null) {
activity.config.timerLastConfig?.let { lastConfig ->
timer.label = lastConfig.label
timer.seconds = lastConfig.seconds
timer.soundTitle = lastConfig.soundTitle
timer.soundUri = lastConfig.soundUri
timer.vibrate = lastConfig.vibrate
}
}
}
private fun updateAlarmTime() {
view.edit_timer_initial_time.text = activity.getFormattedTime(timer.seconds * 60, false, true)
}
private fun changeDuration(timer: Timer) {
MyTimePickerDialogDialog(activity, timer.seconds) { seconds ->
val timerSeconds = if (seconds <= 0) 10 else seconds
timer.seconds = timerSeconds
view.edit_timer_initial_time.text = timerSeconds.getFormattedDuration()
}
}
fun updateAlarmSound(alarmSound: AlarmSound) {
timer.soundTitle = alarmSound.title
timer.soundUri = alarmSound.uri
timer.channelId = null
view.edit_timer_sound.text = alarmSound.title
}
}

View File

@ -85,6 +85,10 @@ fun Context.createNewAlarm(timeInMinutes: Int, weekDays: Int): Alarm {
return Alarm(0, timeInMinutes, weekDays, false, false, defaultAlarmSound.title, defaultAlarmSound.uri, "")
}
fun Context.createNewTimer(): Timer {
return Timer(null, config.timerSeconds, config.timerState, config.timerVibrate, config.timerSoundUri, config.timerSoundTitle, config.timerLabel ?: "", System.currentTimeMillis(), config.timerChannelId, )
}
fun Context.scheduleNextAlarm(alarm: Alarm, showToast: Boolean) {
val calendar = Calendar.getInstance()
calendar.firstDayOfWeek = Calendar.MONDAY
@ -166,7 +170,8 @@ fun Context.hideNotification(id: Int) {
fun Context.hideTimerNotification() = hideNotification(TIMER_NOTIF_ID)
fun Context.updateWidgets() {
val widgetsCnt = AppWidgetManager.getInstance(applicationContext)?.getAppWidgetIds(ComponentName(applicationContext, MyWidgetDateTimeProvider::class.java)) ?: return
val widgetsCnt =
AppWidgetManager.getInstance(applicationContext)?.getAppWidgetIds(ComponentName(applicationContext, MyWidgetDateTimeProvider::class.java)) ?: return
if (widgetsCnt.isNotEmpty()) {
val ids = intArrayOf(R.xml.widget_date_time_info)
Intent(applicationContext, MyWidgetDateTimeProvider::class.java).apply {
@ -179,7 +184,8 @@ fun Context.updateWidgets() {
@SuppressLint("NewApi")
fun Context.scheduleNextWidgetUpdate() {
val widgetsCnt = AppWidgetManager.getInstance(applicationContext)?.getAppWidgetIds(ComponentName(applicationContext, MyWidgetDateTimeProvider::class.java)) ?: return
val widgetsCnt =
AppWidgetManager.getInstance(applicationContext)?.getAppWidgetIds(ComponentName(applicationContext, MyWidgetDateTimeProvider::class.java)) ?: return
if (widgetsCnt.isEmpty()) {
return
}

View File

@ -8,8 +8,11 @@ import androidx.fragment.app.Fragment
import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.SimpleActivity
import com.simplemobiletools.clock.adapters.TimerAdapter
import com.simplemobiletools.clock.dialogs.EditTimerDialog
import com.simplemobiletools.clock.extensions.config
import com.simplemobiletools.clock.extensions.createNewTimer
import com.simplemobiletools.clock.extensions.timerHelper
import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.clock.models.TimerEvent
import com.simplemobiletools.commons.extensions.hideKeyboard
import com.simplemobiletools.commons.extensions.updateTextColors
@ -27,6 +30,7 @@ class TimerFragment : Fragment() {
private lateinit var timerAdapter: TimerAdapter
private var timerPositionToScrollTo = INVALID_POSITION
private var storedTextColor = 0
private var currentEditAlarmDialog: EditTimerDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -40,9 +44,7 @@ class TimerFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
view = (inflater.inflate(R.layout.fragment_timer, container, false) as ViewGroup).apply {
timerAdapter = TimerAdapter(requireActivity() as SimpleActivity) {
refreshTimers()
}
timerAdapter = TimerAdapter(requireActivity() as SimpleActivity, ::refreshTimers, ::openEditTimer)
storeStateVariables()
@ -50,9 +52,9 @@ class TimerFragment : Fragment() {
timers_list.itemAnimator = null
timer_add.setOnClickListener {
activity?.hideKeyboard(it)
activity?.timerHelper?.insertNewTimer {
refreshTimers(true)
activity?.run {
hideKeyboard()
openEditTimer(createNewTimer())
}
}
@ -75,7 +77,6 @@ class TimerFragment : Fragment() {
storeStateVariables()
}
private fun refreshTimers(scrollToLatest: Boolean = false) {
activity?.timerHelper?.getTimers { timers ->
timerAdapter.submitList(timers) {
@ -101,7 +102,7 @@ class TimerFragment : Fragment() {
}
fun updateAlarmSound(alarmSound: AlarmSound) {
timerAdapter.updateAlarmSoundForSelectedTimer(alarmSound)
currentEditAlarmDialog?.updateAlarmSound(alarmSound)
}
fun updatePosition(timerId: Long) {
@ -118,4 +119,11 @@ class TimerFragment : Fragment() {
}
}
}
private fun openEditTimer(timer: Timer) {
currentEditAlarmDialog = EditTimerDialog(activity as SimpleActivity, timer) {
currentEditAlarmDialog = null
refreshTimers()
}
}
}

View File

@ -5,6 +5,7 @@ import android.media.RingtoneManager
import com.simplemobiletools.clock.extensions.gson.gson
import com.simplemobiletools.clock.models.Alarm
import com.simplemobiletools.clock.models.StateWrapper
import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.clock.models.TimerState
import com.simplemobiletools.commons.extensions.getDefaultAlarmSound
import com.simplemobiletools.commons.extensions.getDefaultAlarmTitle
@ -79,6 +80,12 @@ class Config(context: Context) : BaseConfig(context) {
}
set(alarm) = prefs.edit().putString(ALARM_LAST_CONFIG, gson.toJson(alarm)).apply()
var timerLastConfig: Timer?
get() = prefs.getString(TIMER_LAST_CONFIG, null)?.let { lastAlarm ->
gson.fromJson(lastAlarm, Timer::class.java)
}
set(alarm) = prefs.edit().putString(TIMER_LAST_CONFIG, gson.toJson(alarm)).apply()
var timerChannelId: String?
get() = prefs.getString(TIMER_CHANNEL_ID, null)
set(id) = prefs.edit().putString(TIMER_CHANNEL_ID, id).apply()

View File

@ -20,6 +20,7 @@ const val TIMER_LABEL = "timer_label"
const val TIMER_MAX_REMINDER_SECS = "timer_max_reminder_secs"
const val ALARM_MAX_REMINDER_SECS = "alarm_max_reminder_secs"
const val ALARM_LAST_CONFIG = "alarm_last_config"
const val TIMER_LAST_CONFIG = "timer_last_config"
const val USE_TEXT_SHADOW = "use_text_shadow"
const val INCREASE_VOLUME_GRADUALLY = "increase_volume_gradually"
const val ALARMS_SORT_BY = "alarms_sort_by"

View File

@ -1,7 +1,6 @@
package com.simplemobiletools.clock.helpers
import android.content.Context
import com.simplemobiletools.clock.extensions.config
import com.simplemobiletools.clock.extensions.timerDb
import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
@ -34,24 +33,4 @@ class TimerHelper(val context: Context) {
callback.invoke()
}
}
fun insertNewTimer(callback: () -> Unit = {}) {
ensureBackgroundThread {
val config = context.config
timerDao.insertOrUpdateTimer(
Timer(
id = null,
seconds = config.timerSeconds,
state = config.timerState,
vibrate = config.timerVibrate,
soundUri = config.timerSoundUri,
soundTitle = config.timerSoundTitle,
label = config.timerLabel ?: "",
createdAt = System.currentTimeMillis(),
channelId = config.timerChannelId,
)
)
callback.invoke()
}
}
}

View File

@ -5,13 +5,13 @@ import androidx.room.PrimaryKey
@Entity(tableName = "timers")
data class Timer(
@PrimaryKey(autoGenerate = true) val id: Long?,
val seconds: Int,
@PrimaryKey(autoGenerate = true) var id: Long?,
var seconds: Int,
val state: TimerState,
val vibrate: Boolean,
val soundUri: String,
val soundTitle: String,
val label: String,
val createdAt: Long,
val channelId: String? = null,
var vibrate: Boolean,
var soundUri: String,
var soundTitle: String,
var label: String,
var createdAt: Long,
var channelId: String? = null,
)

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/edit_timer_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/edit_timer_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/edit_timer_initial_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawableLeft="@drawable/ic_timer"
android:drawablePadding="@dimen/normal_margin"
android:padding="@dimen/activity_margin"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintTop_toTopOf="parent"
tools:text="05:00" />
<RelativeLayout
android:id="@+id/edit_timer_vibrate_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"
app:layout_constraintTop_toBottomOf="@+id/edit_timer_initial_time">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/edit_timer_vibrate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:drawableLeft="@drawable/ic_vibrate_vector"
android:drawablePadding="@dimen/normal_margin"
android:text="@string/vibrate"
android:textSize="@dimen/bigger_text_size" />
</RelativeLayout>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/edit_timer_sound"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawableLeft="@drawable/ic_bell_vector"
android:drawablePadding="@dimen/normal_margin"
android:padding="@dimen/activity_margin"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintTop_toBottomOf="@+id/edit_timer_vibrate_holder"
tools:text="Default Alarm" />
<LinearLayout
android:id="@+id/edit_timer_label_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/medium_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_timer_sound"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="spread_inside">
<ImageView
android:id="@+id/edit_timer_label_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_label_vector" />
<com.simplemobiletools.commons.views.MyEditText
android:id="@+id/edit_timer_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:hint="@string/label"
android:maxLines="1"
android:singleLine="true"
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -1,145 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:foreground="@drawable/selector">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/timer_time"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/normal_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_horizontal"
android:padding="@dimen/small_margin"
android:textSize="@dimen/stopwatch_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="00:00" />
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/timer_initial_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin"
android:background="?attr/selectableItemBackground"
android:drawableStart="@drawable/ic_timer"
android:drawablePadding="@dimen/normal_margin"
android:padding="@dimen/activity_margin"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintTop_toBottomOf="@+id/timer_time"
tools:text="05:00" />
<RelativeLayout
android:id="@+id/timer_vibrate_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"
app:layout_constraintTop_toBottomOf="@+id/timer_initial_time">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/timer_vibrate"
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/timer_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:drawableStart="@drawable/ic_vibrate_vector"
android:drawablePadding="@dimen/normal_margin"
android:text="@string/vibrate"
android:textSize="@dimen/bigger_text_size" />
android:layout_marginTop="@dimen/bigger_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_horizontal"
android:padding="@dimen/small_margin"
android:textSize="@dimen/stopwatch_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="00:00" />
</RelativeLayout>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/timer_sound"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawableStart="@drawable/ic_bell_vector"
android:drawablePadding="@dimen/normal_margin"
android:padding="@dimen/activity_margin"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintTop_toBottomOf="@+id/timer_vibrate_holder"
tools:text="Default alarm" />
<LinearLayout
android:id="@+id/timer_label_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/medium_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/timer_sound"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="spread_inside">
<ImageView
android:id="@+id/timer_label_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_label_vector" />
<com.simplemobiletools.commons.views.MyEditText
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/timer_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:hint="@string/label"
android:ellipsize="end"
android:gravity="center"
android:includeFontPadding="false"
android:maxLines="1"
android:singleLine="true"
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size" />
</LinearLayout>
android:paddingStart="@dimen/small_margin"
android:paddingEnd="@dimen/small_margin"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/timer_time"
tools:text="Cook rice" />
<ImageView
android:id="@+id/timer_reset"
android:layout_width="@dimen/stopwatch_button_small_size"
android:layout_height="@dimen/stopwatch_button_small_size"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_reset_vector"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/timer_play_pause"
app:layout_constraintEnd_toStartOf="@+id/timer_play_pause"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/timer_play_pause" />
<ImageView
android:id="@+id/timer_delete"
android:layout_width="@dimen/stopwatch_button_small_size"
android:layout_height="@dimen/stopwatch_button_small_size"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_delete_vector"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/timer_play_pause"
app:layout_constraintEnd_toStartOf="@+id/timer_play_pause"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/timer_play_pause"
tools:visibility="visible" />
<ImageView
android:id="@+id/timer_reset"
android:layout_width="@dimen/stopwatch_button_small_size"
android:layout_height="@dimen/stopwatch_button_small_size"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_reset_vector"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/timer_play_pause"
app:layout_constraintEnd_toStartOf="@+id/timer_play_pause"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/timer_play_pause" />
<ImageView
android:id="@+id/timer_play_pause"
android:layout_width="@dimen/stopwatch_button_size"
android:layout_height="@dimen/stopwatch_button_size"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/big_margin"
android:layout_marginBottom="@dimen/big_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_play_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/timer_label_holder" />
<ImageView
android:id="@+id/timer_delete"
android:layout_width="@dimen/stopwatch_button_small_size"
android:layout_height="@dimen/stopwatch_button_small_size"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_delete_vector"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/timer_play_pause"
app:layout_constraintEnd_toStartOf="@+id/timer_play_pause"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/timer_play_pause"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/timer_play_pause"
android:layout_width="@dimen/stopwatch_button_size"
android:layout_height="@dimen/stopwatch_button_size"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/big_margin"
android:layout_marginBottom="@dimen/big_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_play_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/timer_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>