ref: change timer UI to use RecyclerView

- update commons library
This commit is contained in:
Paul Akhamiogu 2021-09-03 19:42:25 +01:00
parent 8d6b5770ed
commit 2e78d67529
38 changed files with 219 additions and 227 deletions

View File

@ -67,7 +67,7 @@ android {
} }
dependencies { dependencies {
implementation 'com.github.SimpleMobileTools:Simple-Commons:ac45c5e893' implementation 'com.github.SimpleMobileTools:Simple-Commons:554dda71a4'
implementation 'com.facebook.stetho:stetho:1.5.0' implementation 'com.facebook.stetho:stetho:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.shawnlin:number-picker:2.4.6' implementation 'com.shawnlin:number-picker:2.4.6'

View File

@ -1,5 +1,6 @@
package com.simplemobiletools.clock.adapters package com.simplemobiletools.clock.adapters
import android.graphics.Color
import android.media.AudioManager import android.media.AudioManager
import android.media.RingtoneManager import android.media.RingtoneManager
import android.view.LayoutInflater import android.view.LayoutInflater
@ -14,13 +15,13 @@ import com.simplemobiletools.clock.dialogs.MyTimePickerDialogDialog
import com.simplemobiletools.clock.extensions.* import com.simplemobiletools.clock.extensions.*
import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID import com.simplemobiletools.clock.helpers.PICK_AUDIO_FILE_INTENT_ID
import com.simplemobiletools.clock.models.Timer import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.clock.models.TimerEvent
import com.simplemobiletools.clock.models.TimerState import com.simplemobiletools.clock.models.TimerState
import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog
import com.simplemobiletools.commons.extensions.getDefaultAlarmSound import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.extensions.getFormattedDuration
import com.simplemobiletools.commons.extensions.onTextChangeListener
import com.simplemobiletools.commons.models.AlarmSound import com.simplemobiletools.commons.models.AlarmSound
import kotlinx.android.synthetic.main.item_timer.view.* import kotlinx.android.synthetic.main.item_timer.view.*
import org.greenrobot.eventbus.EventBus
class TimerAdapter( class TimerAdapter(
private val activity: SimpleActivity, private val activity: SimpleActivity,
@ -39,6 +40,15 @@ 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 { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimerViewHolder {
return TimerViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_timer, parent, false)) return TimerViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_timer, parent, false))
} }
@ -47,52 +57,78 @@ class TimerAdapter(
holder.bind(getItem(position)) holder.bind(getItem(position))
} }
fun getItemAt(position: Int): Timer { fun updateTextColor(textColor: Int) {
return getItem(position) this.textColor = textColor
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) { inner class TimerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init { init {
itemView.timer_label.onTextChangeListener { text -> itemView.timer_label.onTextChangeListener { text ->
updateTimer(getItemAt(adapterPosition).copy(label = text), false) updateTimer(getItem(adapterPosition).copy(label = text), false)
} }
itemView.post {
val textColor = activity.config.textColor
itemView.timer_initial_time.colorLeftDrawable(textColor)
itemView.timer_vibrate.colorLeftDrawable(textColor)
itemView.timer_sound.colorLeftDrawable(textColor)
}
} }
fun bind(timer: Timer) { fun bind(timer: Timer) {
itemView.apply { 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)
timer_delete.applyColorFilter(textColor)
}
timer_label.setTextColor(textColor)
timer_label.setHintTextColor(textColor.adjustAlpha(0.7f))
//only update when different to prevent flickering and unnecessary updates //only update when different to prevent flickering and unnecessary updates
if (timer_label.text.toString() != timer.label) { if (timer_label.text.toString() != timer.label) {
timer_label.setText(timer.label) timer_label.setText(timer.label)
} }
timer_initial_time.text = timer.seconds.getFormattedDuration() timer_initial_time.text = timer.seconds.getFormattedDuration()
timer_initial_time.setTextColor(textColor)
timer_vibrate.isChecked = timer.vibrate 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_sound.text = timer.soundTitle timer_time.setTextColor(textColor)
timer_time.text = when (timer.state) {
is TimerState.Finished -> 0.getFormattedDuration()
is TimerState.Idle -> timer.seconds.getFormattedDuration()
is TimerState.Paused -> timer.state.tick.getFormattedDuration()
is TimerState.Running -> timer.state.tick.getFormattedDuration()
}
timer_time.setOnClickListener { timer_time.setOnClickListener {
changeDuration(timer) changeDuration(timer)
} }
timer_initial_time.setTextColor(textColor)
timer_initial_time.setOnClickListener { timer_initial_time.setOnClickListener {
changeDuration(timer) changeDuration(timer)
} }
timer_vibrate_holder.setOnClickListener {
timer_vibrate.toggle()
updateTimer(timer.copy(vibrate = timer_vibrate.isChecked), false)
}
timer_sound.text = timer.soundTitle
timer_sound.setTextColor(textColor)
timer_sound.setOnClickListener { timer_sound.setOnClickListener {
selectedTimer = timer
SelectAlarmSoundDialog(activity, timer.soundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID, SelectAlarmSoundDialog(activity, timer.soundUri, AudioManager.STREAM_ALARM, PICK_AUDIO_FILE_INTENT_ID,
RingtoneManager.TYPE_ALARM, true, RingtoneManager.TYPE_ALARM, true,
onAlarmPicked = { sound -> onAlarmPicked = { sound ->
@ -110,25 +146,38 @@ class TimerAdapter(
}) })
} }
timer_delete.applyColorFilter(textColor)
when (timer.state) { timer_delete.setOnClickListener {
is TimerState.Finished -> { activity.timerHelper.deleteTimer(timer.id!!) {
timer_time.text = 0.getFormattedDuration() onRefresh.invoke()
}
} }
is TimerState.Idle -> { timer_reset.applyColorFilter(textColor)
timer_time.text = timer.seconds.getFormattedDuration() timer_reset.setOnClickListener {
stopTimer(timer)
} }
is TimerState.Paused -> {
timer_time.text = timer.state.tick.getFormattedDuration() timer_play_pause.setOnClickListener {
when (val state = timer.state) {
is TimerState.Idle -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
is TimerState.Paused -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, state.tick))
is TimerState.Running -> EventBus.getDefault().post(TimerEvent.Pause(timer.id!!, state.tick))
is TimerState.Finished -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
}
}
updateViewStates(timer.state)
}
} }
is TimerState.Running -> { private fun updateViewStates(state: TimerState) {
timer_time.text = timer.state.tick.getFormattedDuration() val resetPossible = state is TimerState.Running || state is TimerState.Paused || state is TimerState.Finished
} itemView.timer_reset.beInvisibleIf(!resetPossible)
} itemView.timer_delete.beInvisibleIf(!(!resetPossible && itemCount > 1))
} val drawableId = if (state is TimerState.Running) R.drawable.ic_pause_vector else R.drawable.ic_play_vector
val iconColor = if (adjustedPrimaryColor == Color.WHITE) Color.BLACK else Color.WHITE
itemView.timer_play_pause.setImageDrawable(activity.resources.getColoredDrawableWithColor(drawableId, iconColor))
} }
} }
@ -139,6 +188,10 @@ class TimerAdapter(
} }
} }
fun updateAlarmSoundForSelectedTimer(alarmSound: AlarmSound) {
selectedTimer?.let { updateAlarmSound(it, alarmSound) }
}
fun updateAlarmSound(timer: Timer, alarmSound: AlarmSound) { fun updateAlarmSound(timer: Timer, alarmSound: AlarmSound) {
updateTimer(timer.copy(soundTitle = alarmSound.title, soundUri = alarmSound.uri, channelId = null)) updateTimer(timer.copy(soundTitle = alarmSound.title, soundUri = alarmSound.uri, channelId = null))
} }
@ -150,4 +203,10 @@ class TimerAdapter(
} }
} }
} }
private fun stopTimer(timer: Timer) {
EventBus.getDefault().post(TimerEvent.Reset(timer.id!!, timer.seconds.secondsToMillis))
activity.hideTimerNotification()
}
} }

View File

@ -1,26 +1,22 @@
package com.simplemobiletools.clock.fragments package com.simplemobiletools.clock.fragments
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.simplemobiletools.clock.R import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.SimpleActivity import com.simplemobiletools.clock.activities.SimpleActivity
import com.simplemobiletools.clock.adapters.TimerAdapter import com.simplemobiletools.clock.adapters.TimerAdapter
import com.simplemobiletools.clock.extensions.config import com.simplemobiletools.clock.extensions.config
import com.simplemobiletools.clock.extensions.hideTimerNotification
import com.simplemobiletools.clock.extensions.secondsToMillis
import com.simplemobiletools.clock.extensions.timerHelper import com.simplemobiletools.clock.extensions.timerHelper
import com.simplemobiletools.clock.models.Timer
import com.simplemobiletools.clock.models.TimerEvent import com.simplemobiletools.clock.models.TimerEvent
import com.simplemobiletools.clock.models.TimerState import com.simplemobiletools.commons.extensions.hideKeyboard
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.models.AlarmSound import com.simplemobiletools.commons.models.AlarmSound
import kotlinx.android.synthetic.main.fragment_timer.timer_view_pager import kotlinx.android.synthetic.main.fragment_timer.timer_fragment
import kotlinx.android.synthetic.main.fragment_timer.view.* import kotlinx.android.synthetic.main.fragment_timer.view.timer_add
import kotlinx.android.synthetic.main.fragment_timer.view.timers_list
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
@ -30,6 +26,7 @@ class TimerFragment : Fragment() {
private lateinit var view: ViewGroup private lateinit var view: ViewGroup
private lateinit var timerAdapter: TimerAdapter private lateinit var timerAdapter: TimerAdapter
private var timerPositionToScrollTo = INVALID_POSITION private var timerPositionToScrollTo = INVALID_POSITION
private var storedTextColor = 0
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -47,22 +44,10 @@ class TimerFragment : Fragment() {
refreshTimers() refreshTimers()
} }
timer_view_pager.adapter = timerAdapter storeStateVariables()
//set empty page transformer to disable item animations
timer_view_pager.setPageTransformer { _, _ -> }
timer_view_pager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
updateViews(position)
}
})
activity?.let {
val textColor = it.config.textColor
indicator_view.setSelectedDotColor(textColor)
indicator_view.setDotColor(textColor.adjustAlpha(0.5f))
indicator_view.attachToPager(timer_view_pager)
}
timers_list.adapter = timerAdapter
timers_list.itemAnimator = null
timer_add.setOnClickListener { timer_add.setOnClickListener {
activity?.hideKeyboard(it) activity?.hideKeyboard(it)
@ -71,70 +56,43 @@ class TimerFragment : Fragment() {
} }
} }
activity?.updateTextColors(timer_fragment)
val textColor = requireContext().config.textColor
timer_play_pause.background =
resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, requireActivity().getAdjustedPrimaryColor())
timer_play_pause.applyColorFilter(if (activity?.getAdjustedPrimaryColor() == Color.WHITE) Color.BLACK else Color.WHITE)
timer_reset.applyColorFilter(textColor)
timer_play_pause.setOnClickListener {
val timer = timerAdapter.getItemAt(timer_view_pager.currentItem)
when (val state = timer.state) {
is TimerState.Idle -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
is TimerState.Paused -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, state.tick))
is TimerState.Running -> EventBus.getDefault().post(TimerEvent.Pause(timer.id!!, state.tick))
is TimerState.Finished -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis))
}
}
timer_reset.setOnClickListener {
val timer = timerAdapter.getItemAt(timer_view_pager.currentItem)
stopTimer(timer)
}
timer_delete.setOnClickListener {
val timer = timerAdapter.getItemAt(timer_view_pager.currentItem)
activity?.timerHelper?.deleteTimer(timer.id!!) {
refreshTimers()
}
}
refreshTimers() refreshTimers()
} }
return view return view
} }
private fun updateViews(position: Int) { override fun onResume() {
activity?.runOnUiThread { super.onResume()
if (timerAdapter.itemCount > position) { requireContext().updateTextColors(timer_fragment)
val timer = timerAdapter.getItemAt(position) val configTextColor = requireContext().config.textColor
updateViewStates(timer.state) if (storedTextColor != configTextColor) {
view.timer_play_pause.beVisible() (view.timers_list.adapter as TimerAdapter).updateTextColor(configTextColor)
} }
} }
override fun onPause() {
super.onPause()
storeStateVariables()
} }
private fun refreshTimers(scrollToLatest: Boolean = false) { private fun refreshTimers(scrollToLatest: Boolean = false) {
activity?.timerHelper?.getTimers { timers -> activity?.timerHelper?.getTimers { timers ->
timerAdapter.submitList(timers) { timerAdapter.submitList(timers) {
view.timer_view_pager.post { view.timers_list.post {
if (timerPositionToScrollTo != INVALID_POSITION && timerAdapter.itemCount > timerPositionToScrollTo) { if (timerPositionToScrollTo != INVALID_POSITION && timerAdapter.itemCount > timerPositionToScrollTo) {
view.timer_view_pager.setCurrentItem(timerPositionToScrollTo, false) view.timers_list.scrollToPosition(timerPositionToScrollTo)
timerPositionToScrollTo = INVALID_POSITION timerPositionToScrollTo = INVALID_POSITION
} else if (scrollToLatest) { } else if (scrollToLatest) {
view.timer_view_pager.setCurrentItem(0, false) view.timers_list.scrollToPosition(timers.lastIndex)
} }
updateViews(timer_view_pager.currentItem)
} }
} }
} }
} }
private fun stopTimer(timer: Timer) { private fun storeStateVariables() {
EventBus.getDefault().post(TimerEvent.Reset(timer.id!!, timer.seconds.secondsToMillis)) storedTextColor = requireContext().config.textColor
activity?.hideTimerNotification()
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
@ -142,31 +100,8 @@ class TimerFragment : Fragment() {
refreshTimers() refreshTimers()
} }
private fun updateViewStates(state: TimerState) {
val resetPossible = state is TimerState.Running || state is TimerState.Paused || state is TimerState.Finished
view.timer_reset.beInvisibleIf(!resetPossible)
view.timer_delete.beInvisibleIf(!(!resetPossible && timerAdapter.itemCount > 1))
val drawableId = if (state is TimerState.Running) {
R.drawable.ic_pause_vector
} else {
R.drawable.ic_play_vector
}
val iconColor = if (activity?.getAdjustedPrimaryColor() == Color.WHITE) {
Color.BLACK
} else {
Color.WHITE
}
view.timer_play_pause.setImageDrawable(resources.getColoredDrawableWithColor(drawableId, iconColor))
}
fun updateAlarmSound(alarmSound: AlarmSound) { fun updateAlarmSound(alarmSound: AlarmSound) {
val timer = timerAdapter.getItemAt(timer_view_pager.currentItem) timerAdapter.updateAlarmSoundForSelectedTimer(alarmSound)
activity?.timerHelper?.insertOrUpdateTimer(timer.copy(soundTitle = alarmSound.title, soundUri = alarmSound.uri)) {
refreshTimers()
}
} }
fun updatePosition(timerId: Long) { fun updatePosition(timerId: Long) {
@ -175,7 +110,7 @@ class TimerFragment : Fragment() {
if (position != INVALID_POSITION) { if (position != INVALID_POSITION) {
activity?.runOnUiThread { activity?.runOnUiThread {
if (timerAdapter.itemCount > position) { if (timerAdapter.itemCount > position) {
view.timer_view_pager.setCurrentItem(position, false) view.timers_list.scrollToPosition(position)
} else { } else {
timerPositionToScrollTo = position timerPositionToScrollTo = position
} }

View File

@ -51,7 +51,6 @@ class TimerHelper(val context: Context) {
channelId = config.timerChannelId, channelId = config.timerChannelId,
) )
) )
callback.invoke() callback.invoke()
} }
} }

View File

@ -9,7 +9,7 @@ import com.simplemobiletools.clock.models.Timer
@Dao @Dao
interface TimerDao { interface TimerDao {
@Query("SELECT * FROM timers ORDER BY createdAt DESC") @Query("SELECT * FROM timers ORDER BY createdAt ASC")
fun getTimers(): List<Timer> fun getTimers(): List<Timer>
@Query("SELECT * FROM timers WHERE id=:id") @Query("SELECT * FROM timers WHERE id=:id")

View File

@ -49,15 +49,9 @@ class TimerService : Service() {
val firstTimer = runningTimers.first() val firstTimer = runningTimers.first()
val formattedDuration = (firstTimer.state as TimerState.Running).tick.getFormattedDuration() val formattedDuration = (firstTimer.state as TimerState.Running).tick.getFormattedDuration()
val contextText = when { val contextText = when {
runningTimers.size > 1 -> { runningTimers.size > 1 -> getString(R.string.timer_multiple_notification_msg, runningTimers.size)
getString(R.string.timer_multiple_notification_msg, runningTimers.size) firstTimer.label.isNotEmpty() -> getString(R.string.timer_single_notification_label_msg, firstTimer.label)
} else -> getString(R.string.timer_single_notification_msg, runningTimers.size)
firstTimer.label.isNotEmpty() -> {
getString(R.string.timer_single_notification_label_msg, firstTimer.label)
}
else -> {
getString(R.string.timer_single_notification_msg, runningTimers.size)
}
} }
startForeground(TIMER_RUNNING_NOTIF_ID, notification(formattedDuration, contextText, firstTimer.id!!)) startForeground(TIMER_RUNNING_NOTIF_ID, notification(formattedDuration, contextText, firstTimer.id!!))
} }

View File

@ -1,11 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
android:strokeWidth="1.6"
android:strokeColor="#FFFFFFFF" />
</vector>

View File

@ -6,87 +6,32 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2 <com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/timer_view_pager" android:id="@+id/timers_list"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="match_parent"
android:layout_marginEnd="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@id/timer_play_pause" android:paddingBottom="@dimen/fab_list_bottom_padding"
app:layout_constraintEnd_toStartOf="@id/indicator_view" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
tools:itemCount="3"
tools:listitem="@layout/item_timer" />
<com.simplemobiletools.clock.views.pageindicator.PagerIndicator <com.simplemobiletools.commons.views.MyFloatingActionButton
android:id="@+id/indicator_view" android:id="@+id/timer_add"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/medium_margin" android:layout_gravity="bottom|end"
app:layout_constraintBottom_toTopOf="@id/timer_play_pause" android:layout_margin="@dimen/activity_margin"
app:layout_constraintEnd_toEndOf="parent" android:contentDescription="@string/new_timer"
app:layout_constraintTop_toTopOf="parent" android:src="@drawable/ic_plus_vector"
app:layout_constraintVertical_bias="0.05" app:backgroundTint="@color/color_primary"
app:spi_orientation="vertical" />
<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"
tools:visibility="gone" />
<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_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_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_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:rippleColor="@color/pressed_item_foreground" />
<ImageView
android:id="@+id/timer_add"
android:layout_width="@dimen/stopwatch_button_size"
android:layout_height="@dimen/stopwatch_button_size"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/big_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_add_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/timer_play_pause" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/timer_time" android:id="@+id/timer_time"
@ -75,7 +75,6 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/activity_margin" android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/medium_margin" android:paddingBottom="@dimen/medium_margin"
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"
app:layout_constraintTop_toBottomOf="@+id/timer_sound" app:layout_constraintTop_toBottomOf="@+id/timer_sound"
@ -100,4 +99,47 @@
android:textSize="@dimen/normal_text_size" /> android:textSize="@dimen/normal_text_size" />
</LinearLayout> </LinearLayout>
<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_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" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Saat bölməsi</string> <string name="clock_tab">Saat bölməsi</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Záložka hodin</string> <string name="clock_tab">Záložka hodin</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Tab cloc</string> <string name="clock_tab">Tab cloc</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Ur</string> <string name="clock_tab">Ur</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Uhr</string> <string name="clock_tab">Uhr</string>

View File

@ -23,6 +23,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Ετικέτα Ρολογιού</string> <string name="clock_tab">Ετικέτα Ρολογιού</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Pestaña de reloj</string> <string name="clock_tab">Pestaña de reloj</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Erloju fitxa</string> <string name="clock_tab">Erloju fitxa</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
   
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Kello-välilehti</string> <string name="clock_tab">Kello-välilehti</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Horloge</string> <string name="clock_tab">Horloge</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Kartica sata</string> <string name="clock_tab">Kartica sata</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Tab jam</string> <string name="clock_tab">Tab jam</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Tab jam</string> <string name="clock_tab">Tab jam</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Scheda orologio</string> <string name="clock_tab">Scheda orologio</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">時計</string> <string name="clock_tab">時計</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Laikrodžio skirtukas</string> <string name="clock_tab">Laikrodžio skirtukas</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">ക്ലോക്ക് ടാബ്</string> <string name="clock_tab">ക്ലോക്ക് ടാബ്</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Klokke</string> <string name="clock_tab">Klokke</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Tab Klok</string> <string name="clock_tab">Tab Klok</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Zegar</string> <string name="clock_tab">Zegar</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Relógio</string> <string name="clock_tab">Relógio</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Часы</string> <string name="clock_tab">Часы</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Okno s časom</string> <string name="clock_tab">Okno s časom</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Fliken Klocka</string> <string name="clock_tab">Fliken Klocka</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Saat sekmesi</string> <string name="clock_tab">Saat sekmesi</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Годинник</string> <string name="clock_tab">Годинник</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">时钟页面</string> <string name="clock_tab">时钟页面</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">時鐘頁面</string> <string name="clock_tab">時鐘頁面</string>

View File

@ -22,6 +22,7 @@
<string name="timer_multiple_notification_msg">%d timers are running</string> <string name="timer_multiple_notification_msg">%d timers are running</string>
<string name="timer_single_notification_label_msg">Timer for %s is running</string> <string name="timer_single_notification_label_msg">Timer for %s is running</string>
<string name="timer_single_notification_msg">%d timer is running</string> <string name="timer_single_notification_msg">%d timer is running</string>
<string name="new_timer">New Timer</string>
<!-- Settings --> <!-- Settings -->
<string name="clock_tab">Clock tab</string> <string name="clock_tab">Clock tab</string>