Могу ли я иметь "мягкую клавиатуру" "adjustResize" и панель инструментов за панель состояния одновременно?
В моем приложении Android для меня очень важно использовать поведение adjustResize
для мягкой клавиатуры. Таким образом, пользователи могут прокручивать вниз до других элементов пользовательского интерфейса, например, кнопку "продолжить".
Я заметил, что adjustResize
работает только тогда, когда у меня есть параметр Manifest и android:fitsSystemWindows="true"
в корневом элементе макета. (Пожалуйста, поправьте меня, если я ошибаюсь!)
Но с android:fitsSystemWindows="true"
панель инструментов больше не сидит за панель состояния. Что имеет смысл, но не то, что я хочу.
Когда панель инструментов находится за ней, строка состояния имеет соответствующий темный оттенок цвета панели инструментов. То, что у меня есть с android:fitsSystemWindows="true"
, - это бесцветная строка состояния и панель инструментов, которая находится на 24dp ниже, чем я хочу.
Я откажусь от соответствующей цветной строки состояния для поведения клавиатуры adjustResize
. Но мой вопрос: возможно ли иметь и то и другое? Смею ли я мечтать о красоте и доступности?
Кто-нибудь более опытный знает магическое сочетание настроек?
Или, возможно, как работа вокруг, способ явно окрасить строку состояния?
FYI:
Это действия с корневыми элементами RelativeLayout, а в некоторых из них есть ListView
и EditText
.
Панель инструментов android.support.v7.widget.Toolbar
Потенциально соответствующие элементы стиля:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">@null</item>
PS - Я читал десятки подобных вопросов о мягкой клавиатуре, но не смог найти ничего полезного в непреднамеренных эффектах на панели инструментов. Также наоборот, много вопросов о стиле панели инструментов/статусов, но ничего похожего на это. Тем не менее, извините, если я что-то пропустил!
Большое спасибо заранее!
Edit
Я играл с удалением android:fitsSystemWindows="true"
и добавляю больше ScrollViews или пытаюсь получить все в одном ScrollView. Это ничего не делает.
Если я удалю android:fitsSystemWindows="true"
, тогда нижняя часть пользовательского интерфейса "склеивается" в нижней части экрана - он не "изменяет размер", а вместо этого приклеивается к верхней части мягкой клавиатуры, как я ожидал бы от нее с adjustResize
, установленным в манифесте.
Настройка android:fitsSystemWindows="true"
в корневом представлении делает изменение размера пользовательского интерфейса, как и следовало ожидать, но это также заставляет панель больше не заходить за статусBar.
Итак, я все еще точно начинаю: (
Добавление образца XML-кода макета:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- CoordinatorLayout because this view uses SnackBars -->
<!-- Relative Layout to lock "continue" button bar to bottom -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Main content, that scrolls with or without keyboard -->
<!-- Correctly sits behind transparent Status Bar -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/footer_persistent_height">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ACTUAL VIEWS DELETED FOR BREVITY / CLARITY -->
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
<!-- Bottom nav bar -->
<!-- Correctly sits at bottom of UI when keyboard is not visible -->
<!-- PROBLEM: Not accessible when soft keyboard is visible -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
style="?android:attr/buttonBarStyle">
<Button
android:id="@+id/skip_button"
android:theme="@style/ButtonContinueGrey"
android:onClick="skipClickHandler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
<Button
android:id="@+id/button_progress"
android:theme="@style/ButtonContinueColored"
android:onClick="continueClickHandler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
</LinearLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Ответы
Ответ 1
(Отвечая на мой собственный вопрос)
Это похоже на ошибку в android:
https://code.google.com/p/android/issues/detail?id=63777
Сообщения об этом сообщении об ошибке сообщают о нескольких предлагаемых работах, таких как создание настраиваемого класса Layout или специальной Soft Keyboard.
Мне кажется, что я уже потратил достаточно времени на это. Поэтому мое решение состоит в том, чтобы просто вручную пометить строку состояния.
Решение:
-
Установите android:fitsSystemWindows="true"
в корневом представлении макета или глобально в style.xml. Это (наряду с adjustResize в манифесте) заставляет пользовательский интерфейс сжиматься над Soft Keyboard, поэтому пользовательский интерфейс не блокируется - самое главное.
-
Цвет строки состояния. Это возможно только в Lollypop и новее. Во всяком случае, это то же самое, что и прозрачный StatusBar.
private void updateStatusBarColor(){
// Check Version
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// OPTIONAL: Calculate a darker version of the toolbar color
int color = calculateDarkerColor(toolBarColor);
// Get the statusBar
Window window = getWindow();
// You can't color a transparent statusbar
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// Set the color
window.setStatusBarColor(color);
}
}
// Calculate a darker version of a given color
// Note I do this because the color always changes, if it always the same I would save the darker version as a Resource in colors.xml
private int calculateDarkerColor(int color){
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] *= 0.8f; // smaller = darker
return Color.HSVToColor(hsv);
}
Ответ 2
Попробуйте сохранить макет в режиме прокрутки и удалить андроид: fitsSystemWindows = "true" и использовать только отрегулировать размер
Ответ 3
Я не получил ваш вопрос правильно, но насколько я могу понять, чтобы решить проблему -
Для проблемы с дополнением попробуйте добавить
android:fitsSystemWindows="true"
android:clipToPadding="false"
И для прозрачной строки состояния добавьте
<item name="android:statusBarColor">@android:color/transparent</item>
в AppTheme.
Надеюсь, что это поможет отдохнуть, пожалуйста, загрузите скриншот своей проблемы для подробного просмотра проблемы.
Ответ 4
Я исправляю вашу проблему, а также тестирую в конце. Пожалуйста, измените свой относительный макет на framelayout следующим образом:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- CoordinatorLayout because this view uses SnackBars -->
<!-- Relative Layout to lock "continue" button bar to bottom -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- Main content, that scrolls with or without keyboard -->
<!-- Correctly sits behind transparent Status Bar -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="24dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ACTUAL VIEWS DELETED FOR BREVITY / CLARITY -->
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
<!-- Bottom nav bar -->
<!-- Correctly sits at bottom of UI when keyboard is not visible -->
<!-- PROBLEM: Not accessible when soft keyboard is visible -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
style="?android:attr/buttonBarStyle"
android:layout_gravity="bottom">
<Button
android:id="@+id/skip_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
<Button
android:id="@+id/button_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
</LinearLayout>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
Ответ 5
Я нашел решение, которое, похоже, хорошо работает с ОС. Сначала установите fitSystemWindows = true
на представление, которое вы хотите отреагировать на окно, а затем сообщите ему, чтобы игнорировать верхнее дополнение:
ViewCompat.setOnApplyWindowInsetsListener(yourView, (view, insets) ->
ViewCompat.onApplyWindowInsets(yourView,
insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0,
insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()))
);
Подробнее здесь: https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec