Фон
Мне нужно сделать вид, похожий на панель набора номера, как в приложении "Телефон".
Я использую GridLayout представлений. Каждая ячейка имеет одинаковый размер и содержит простой TextView, который при необходимости должен изменить размер шрифта.
Эта проблема
Мне это удалось, но по какой-то причине это не работает в соответствии с предоставленным пространством.
Если на нем много места, он отлично работает:
Однако, когда он становится меньше (пример: маленькие экраны, альбомная ориентация, разделенное окно ...), становятся видимыми только верхние кнопки сетки, и они даже не меняют размер своего шрифта, как будто все они хотят быть самого большого размера они могут:
Что я пробовал
Я пытался изменить различные атрибуты представлений, но ничего не помогло.
Я знаю, однако, что панель набора номера в приложении «Телефон» на самом деле не меняет размер шрифта. До некоторого размера он отображается нормально, а если он слишком мал, он меняется на другой макет. Это особенно важно для ландшафтного режима и режима разделенного окна.
Вот код, который я сделал (я изменяю значение layout_constraintHeight_percent, чтобы проверить различные размеры верхней области):
градиент
...
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
...
QueryKeyboard.kt
class QueryKeyboard @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : GridLayout(context, attrs, defStyle) {
init {
orientation = HORIZONTAL
clipChildren = false
clipToPadding = false
columnCount = 3
rowCount = 4
//workaround for a weird issue of seeing just 3 huge buttons, instead of all
val runnable = Runnable {
for (i in 1..9)
addView(generateGridTextButton(i.toString()))
addView(generateGridTextButton("*"))
addView(generateGridTextButton("0"))
addView(generateGridTextButton("+"))
}
if (isInEditMode)
runnable.run()
else
this.doOnPreDraw { runnable.run() }
}
private fun generateGridTextButton(textToShowAndAddUponClick: CharSequence): TextView {
val tv = LayoutInflater.from(context).inflate(R.layout.grid_text_button, this, false) as TextView
tv.text = textToShowAndAddUponClick
return tv
}
}
grid_text_button.xml
<androidx.appcompat.widget.AppCompatTextView
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="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:breakStrategy="balanced"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="false"
android:gravity="center"
android:textColor="#000"
android:textSize="36dp"
app:autoSizeMaxTextSize="36dp"
app:autoSizeMinTextSize="12dp"
app:layout_columnWeight="1"
app:layout_gravity="fill"
app:layout_rowWeight="1"
tools:layout_gravity="center"
tools:targetApi="m"
tools:text="1" />
Использование в activity_main.xml:
<androidx.constraintlayout.widget.ConstraintLayout
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="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<TextView
android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="0px"
android:background="#33ff0000" android:gravity="center" android:text="some content"
app:layout_constraintBottom_toTopOf="@id/queryKeyboard" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.6" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.sample.myapplication.QueryKeyboard
android:id="@+id/queryKeyboard" android:layout_width="match_parent" android:layout_height="0px"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
РЕДАКТИРОВАТЬ: я попытался обернуть TextView с помощью FrameLayout, чтобы показать размер каждой ячейки:
grid_text_button.xml
<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="wrap_content" android:layout_height="wrap_content"
app:layout_columnWeight="1" app:layout_gravity="fill" app:layout_rowWeight="1">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless" android:breakStrategy="balanced"
android:clickable="true" android:focusable="true" android:focusableInTouchMode="false" android:gravity="center"
android:textColor="#000" android:textSize="36sp" app:autoSizeMaxTextSize="36sp" app:autoSizeMinTextSize="12sp"
tools:layout_gravity="center" tools:targetApi="m" tools:text="1" />
</FrameLayout>
QueryKeyboard.kt
class QueryKeyboard @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : GridLayout(context, attrs, defStyle) {
private var cellBackgroundColor = 0xffff0000.toInt()
init {
orientation = HORIZONTAL
clipChildren = false
clipToPadding = false
columnCount = 3
rowCount = 4
//workaround for a weird issue of seeing just 3 huge buttons, instead of all
val runnable = Runnable {
for (i in 1..9) {
addView(generateGridTextButton(i.toString()))
}
addView(generateGridTextButton("*"))
addView(generateGridTextButton("0"))
addView(generateGridTextButton("+"))
}
if (isInEditMode)
runnable.run()
else
this.doOnPreDraw { runnable.run() }
}
private fun switchColor() {
cellBackgroundColor = if (cellBackgroundColor == 0xffff0000.toInt()) 0xff00ff00.toInt() else 0xffff0000.toInt()
}
private fun generateGridTextButton(textToShowAndAddUponClick: CharSequence): View {
val view = LayoutInflater.from(context).inflate(R.layout.grid_text_button, this, false)
switchColor()
view.setBackgroundColor(cellBackgroundColor)
view.textView.text = textToShowAndAddUponClick
return view
}
}
И вот 2 случая, когда он работает нормально, а когда нет:
Как и раньше. Получение 3 ячеек, текст не по центру и автоматическое изменение размера шрифта.
Вопросы
Почему ячейки не регулируют свои размеры, включая размер шрифта каждой из них? Почему я вижу всего 3 клетки, когда они слишком маленькие? Как я могу это исправить?
Есть ли лучшая альтернатива? Думаю, я мог бы использовать LinearLayout из нескольких экземпляров LinearLayout, но это просто странно для этого случая ... В конце концов, как часто вы используете GridLayout ... :)
Как я могу определить, когда он слишком мал, чтобы переключиться на другой макет, как в приложении «Телефон», включая все используемые ими случаи (даже с разделенным окном)? Возможно, они просто использовали квалификатор для макетов? Если да, что рекомендуется для этого случая?