Material Time Picker – улучшенный виджет Time Picker из концепции Material Design, который позволяет запустить часы с выбором времени. Давайте сделаем так, что бы при тапе по кнопке мы запускали Material Time Picker и после выбора времени – наши часы сворачивались, а выбранное время записывалось в текстовое поле, которое будет расположено под кнопкой
Итак давайте создадим верстку для нашего Activity с кнопкой и текстовым полем:
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DateTime">
<Button
android:id="@+id/butTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/time"
android:background="@color/colorPrimary"
style="@style/Widget.MaterialComponents.Button.Icon"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/selected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/butTime"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_margin="10dp"
android:textColor="@android:color/black"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Переходим в класс Activity.
А теперь внимание! Для использования этого виджета Вы должны использовать вот эту версию Material Design – 1.3.0-alpha03
После подключения этой версии мы должны во первых перед методом OnCreate нашего класса Activity ввести две переменные – hour, minute. Дело в том, что мы в Material Time Picker можем по умолчанию отобразить текущее время. Это время сначала перед передачей нам нужно получить вот в эти переменные
private var hour = 0
private var minute = 0
Да и наш класс не нужно относить ни к какому интерфейсу времени или даты
class DateTime : AppCompatActivity(),View.OnClickListener
Теперь нам нужно создать метод получения текущего времени и записать в созданные нами переменные
private fun getTime() {
val time = Calendar.getInstance()
hour = time.get(Calendar.HOUR)
minute = time.get(Calendar.MINUTE)
}
Мы создаём объект Calendar, который хранит текущую информацию о времени и даты. После чего мы записываем в наши переменные необходимую нам информацию.
Далее мы создаём метод в котором и будем вызывать наши часы
private fun startTimePicker () {
}
Теперь вызываем метод текущего времени
private fun startTimePicker () {
getTime()
}
После этого мы создаём в этом методе объект часов
@SuppressLint("SetTextI18n")
private fun startTimePicker () {
getTime()
val picker =
MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_24H)
.setHour(hour)
.setMinute(minute)
.setTitleText(getString(R.string.selectTime))
.build()
picker.show(supportFragmentManager, "startTimePicker")
}
setTimeFormat(TimeFormat.CLOCK_24H) – Устанавливает формат времени
setHour(hour) – Записываем часы, которые будут отображаться при запуске часов по умолчанию (мы передаем текущие часы)
setMinute(minute) – Записываем минуты, которые будут отображаться при запуске часов по умолчанию (мы передаем текущие минуты)
setTitleText(getString(R.string.selectTime)) – Записываем заголовок, который будет отображаться на часах
build() – создаёт объект часов show() – запускает наши часы с уникальным тегом (“startTimePicker”) – который может быть любым, но уникальным
У Material Time Picker есть несколько методов addOnPositiveButtonClickListener – запускается при тапе по кнопке подтверждения выбранного времени
addOnNegativeButtonClickListene – запускается при тапе по кнопке отказа выбора времени
addOnCancelListener – запускается при тапе за пределами модуля с часами
addOnDismissListener – запускается при закрытии модуля с часами. То есть срабатывает в любом случае, что бы Вы не сделали
Давайте реализуем эти методы
picker.addOnPositiveButtonClickListener {
binding?.selected?.text = "${picker.hour}:${picker.minute}"
}
picker.addOnNegativeButtonClickListener {
binding?.selected?.text = getString(R.string.cancel)
}
picker.addOnCancelListener {
binding?.selected?.text = getString(R.string.tapCancel)
}
picker.addOnDismissListener {
binding?.butTime?.text = getString(R.string.clockClosed)
}
Итак, при тапе по кнопке подтверждения мы записываем выбранное время в текстовое поле, расположенное под кнопкой
picker.addOnPositiveButtonClickListener {
binding?.selected?.text = "${picker.hour}:${picker.minute}"
}
При тапе по кнопке отказа выбора времени мы запишем сообщение “Отмена” в текстовое поле, которое находится под кнопкой
picker.addOnNegativeButtonClickListener {
binding?.selected?.text = getString(R.string.cancel)
}
Также при тапе по кнопке отказа выбора времени мы запишем сообщение – “Тапнули по кнопке отмена” в текстовое поле, расположенное под кнопкой
picker.addOnCancelListener {
binding?.selected?.text = getString(R.string.tapCancel)
}
Кроме того при каждом закрытии модуля с часами мы будем менять название на кнопке, которая вызывает модуль с часами на – “ЧАСЫ ЗАКРЫТЫ”
picker.addOnDismissListener {
binding?.butTime?.text = getString(R.string.clockClosed)
}
Итак полностью наш код создания объекта с часами, который мы разместили в методе startTimePicker будет выглядеть вот так
@SuppressLint("SetTextI18n")
private fun startTimePicker () {
getTime()
val picker =
MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_24H)
.setHour(hour)
.setMinute(minute)
.setTitleText(getString(R.string.selectTime))
.build()
picker.show(supportFragmentManager, "startTimePicker")
picker.addOnPositiveButtonClickListener {
binding?.selected?.text = "${picker.hour}:${picker.minute}"
}
picker.addOnNegativeButtonClickListener {
binding?.selected?.text = getString(R.string.cancel)
}
picker.addOnCancelListener {
binding?.selected?.text = getString(R.string.tapCancel)
}
picker.addOnDismissListener {
binding?.butTime?.text = getString(R.string.clockClosed)
}
}
Далее нам нужно вызвать этот метод startTimePicker в методе обработки тапа по кнопке, которая должна и запускать наш модуль с часами
override fun onClick(view: View) {
when(view.id) {
R.id.butTime -> startTimePicker()
}
}
Теперь наши часы начнут функционировать
Material Time Picker как и любой виджет из концепции Material Design имеет не только дополнительные атрибуты для настройки внешнего вида, но и шаблонные стили. С ними Вы можете ознакомиться вот на этой странице
Код из этого урока
activity_date_time.xml -xml шаблон Activity
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DateTime">
<Button
android:id="@+id/butTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/time"
android:background="@color/colorPrimary"
style="@style/Widget.MaterialComponents.Button.Icon"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/selected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/butTime"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_margin="10dp"
android:textColor="@android:color/black"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/selected"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_margin="10dp"
android:textColor="@android:color/black"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
DateTime.kt – класс Activity
class DateTime : AppCompatActivity(),View.OnClickListener {
private var binding:ActivityDateTimeBinding? = null
private var hour = 0
private var minute = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_date_time)
binding?.butTime?.setOnClickListener(this)
}
override fun onClick(view: View) {
when(view.id) {
R.id.butTime -> startTimePicker()
}
}
@SuppressLint("SetTextI18n")
private fun startTimePicker () {
getTime()
val picker =
MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_24H)
.setHour(hour)
.setMinute(minute)
.setTitleText(getString(R.string.selectTime))
.build()
picker.show(supportFragmentManager, "startTimePicker")
picker.addOnPositiveButtonClickListener {
binding?.selected?.text = "${picker.hour}:${picker.minute}"
}
picker.addOnNegativeButtonClickListener {
binding?.selected?.text = getString(R.string.cancel)
}
picker.addOnCancelListener {
binding?.selected?.text = getString(R.string.tapCancel)
}
picker.addOnDismissListener {
binding?.butTime?.text = getString(R.string.clockClosed)
}
}
private fun getTime() {
val time = Calendar.getInstance()
hour = time.get(Calendar.HOUR)
minute = time.get(Calendar.MINUTE)
}
}
ДОМАШНЕЕ ЗАДАНИЕ
Создайте часы, которые будет появляться при тапе по кнопке. При выборе времени – выбранное время должно записываться в текстовое поле, которое Вы расположите под кнопкой. Результат в формате видео пришлите на Whats App – +79612777611