Итак, я вчера нашел довольно приличное решение.
Я использовал два текста для редактирования и текстовое представление. Я выровнял их в макете ограничения
<TextView
android:id="@+id/colon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text=":"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/hoursInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:inputType="number"
android:maxLength="3"
android:text="00"
app:layout_constraintBottom_toBottomOf="@id/colon"
app:layout_constraintEnd_toStartOf="@id/colon"
app:layout_constraintTop_toTopOf="@id/colon"
app:layout_constraintVertical_bias="0.0" />
<EditText
android:id="@+id/minutesInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:inputType="number"
android:maxLength="3"
android:text="00"
app:layout_constraintBottom_toBottomOf="@id/colon"
app:layout_constraintStart_toEndOf="@id/colon"
app:layout_constraintTop_toTopOf="@id/colon" />
Поскольку я хотел использовать только цифры, мне пришлось использовать текстовое представление для представления двоеточия. изменил средство просмотра текста для каждого ввода. Я использовал размер строки, чтобы определить, когда нужно полностью обновить текст, и использовал onTextChanged
, чтобы заставить строку всегда иметь минимальный размер 2. И часы, и минуты выглядят одинаково, за исключением позиции enum / курсор , Сами поля позволят ввести третий ди git в позиции курсора. Таким образом, поле с «12» превратится в «123», а затем запустит время обновления, которое выясняет, нужно ли нам устанавливать текст где-либо еще, или отклонять число, или какой-либо другой требуемый лог c.
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (s != null && s.toString().length > 2)
//I used an ENUM to tell my update time function which view I was in. More to come. Cusor position is set in the keylistener
updateTime(s.toString, hoursInput.text, cursorPosition, Field.MINUTES)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null && s.length < 2)
StringBuilder(s).apply { this.insert(0, "0") }.toString().also {
minutesInput.setText(it)
}
}
})
Я также добавил onKeyListener для наблюдения за ключом удаления, специально предназначенного для реализации пользовательских логи c. Но прежде чем он вернет результат нажатия клавиши, я бы отслеживал положение курсора при нажатии клавиши для каждого события. Входы минут и часов выглядят одинаково / одинаково.
setOnKeyListener { _, keyCode, keyEvent ->
if (keyEvent.action == KeyEvent.ACTION_DOWN) cursorPosition = selectionStart
(keyCode == KeyEvent.KEYCODE_DEL && keyEvent.action == KeyEvent.ACTION_DOWN && selectionStart == selectionEnd && selectionStart != 0).also { performDelete ->
if (performDelete) Logic.deleteTime(minutesInputString, minutesInput.text, cursorPosition, Field.Minutes)
}
}
Наконец, у меня есть класс Logi c, который я фактически выполнял для работы со строками.
// Inside update/delete I convert the strings into a string that is like 00129 and use the cursorPosition/Field enum to determine where to add text.
Logic.updateTime(minutesInputString, hoursInputString, cursorPosition, Field) : String[]
Logic.deleteTime(minutesInputString, hoursInputString, cursorPosition, Field): String[]
Затем я сразу установил время с помощью входов.
updateTime(mins, hours, position, Field.MINUTES).also{
// ("00", "129", 2, Minutes) returns as ["01", "29"]
minutesInput.setText(it[0])
minutesInput.setText(it[1])
}
Сложная проблема, над которой все еще ведется работа, но так я ее решил. Внедрение этого решения заняло у меня 4 часа, когда я крутил колеса почти три дня!