• 0
  • Contact Me: alexbashy9001@gmail.com

Material Time Picker

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

Leave a Reply

Your email address will not be published. Required fields are marked *