我可以同时使用"adjustResize"软键盘行为和状态栏后面的工具栏吗?

Kai*_*han 16 keyboard android android-layout android-softkeyboard android-styles

在我的Android应用程序中,对我来说使用adjustResize软键盘的行为至关重要.因此,用户可以向下滚动到其他UI元素,例如"继续"按钮.

我注意到adjustResize只有当我同时具有Manifest设置和android:fitsSystemWindows="true"布局根元素时才会有效.(如果我错了,请纠正我!)

但是android:fitsSystemWindows="true"工具栏不再位于状态栏后面.这很有道理,但不是我想要的.

当工具栏位于其后面时,状态栏具有与工具栏颜色相匹配的深色阴影.我所拥有的android:fitsSystemWindows="true"是一个无色的状态栏和一个比我想要的低24dp的工具栏.

为了adjustResize键盘行为,我会放弃匹配的彩色状态栏.但我的问题是,它们可能同时存在吗?我敢为美丽和无障碍做梦吗?

更有经验的人知道神奇的设置组合吗?或者,或许,作为一种解决方法,明确地为状态栏着色的方法?

供参考:

这些是具有RelativeLayout根元素的活动,其中一些是ListViews和EditTexts.

工具栏是 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>
Run Code Online (Sandbox Code Playgroud)

PS - 我已经阅读了几十个关于软键盘行为的类似问题,但无法找到任何对工具栏的意外影响有用的东西.反之亦然,很多关于工具栏/状态栏行为的Style问题,但看似没什么关系.从来没有,抱歉,如果我错过了什么!

提前谢谢了!

编辑

我一直在玩删除android:fitsSystemWindows="true"和添加更多ScrollViews或尝试将所有内容放入相同的ScrollView.这什么都不做.

如果我删除android:fitsSystemWindows="true"然后UI的底部被"胶合"到屏幕的底部 - 它不会"调整大小"而是粘贴到软键盘的顶部,就像我期望它与adjustResizeManifest中的set一样.

android:fitsSystemWindows="true"在根视图中进行设置会使UI像我期望的那样调整大小 - 但它也会使工具栏不再在statusBar后面绘制.

所以我仍然是我开始的地方:(

添加布局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>
Run Code Online (Sandbox Code Playgroud)

FRR*_*FRR 11

我找到了一个似乎与操作系统兼容的解决方案.首先设置fitSystemWindows = true您想要对窗口作出反应的视图,然后告诉它忽略顶部填充:

  ViewCompat.setOnApplyWindowInsetsListener(yourView, (view, insets) ->
      ViewCompat.onApplyWindowInsets(yourView,
          insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0,
              insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()))
  );
Run Code Online (Sandbox Code Playgroud)

在此处阅读更多内容:https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec

  • 极好的答案。 (3认同)

Kai*_*han 0

(回答我自己的问题)

这似乎是android中的一个错误: https://code.google.com/p/android/issues/detail ?id=63777

上述错误报告中的帖子链接到一些建议的解决方法,例如创建自定义布局类或自定义软键盘。

我觉得我已经在这件事上浪费了足够多的时间了。所以我的解决方案是手动为状态栏着色。

解决方案:

  1. android:fitsSystemWindows="true"在布局的根视图中或在 style.xml 中全局设置。这(与清单中的 adjustmentResize 一起)使 UI 缩小到软键盘上方,因此不会阻塞 UI——这是最重要的事情。

  2. 给状态栏上色。这仅在 Lollypop 及更新版本中可行。无论如何,这与透明状态栏相同。

    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's 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);
    }
    
    Run Code Online (Sandbox Code Playgroud)