如何使用adjustResize设置隐藏键盘下方的BottomNavigationView

wil*_*iff 29 android android-softkeyboard bottomnavigationview

根据材料设计规范,当键盘出现时,BottomNavigationView应该隐藏在它下面.但是,如果我android:windowSoftInputMode="adjustResize"在Activity的清单中设置BottomNavigationView了键盘上方的移动.

我需要设置adjustResize为在键盘打开时滚动到屏幕底部.但是,我不希望它BottomNavigationView是可见的.可以这样做吗?

它目前的样子:

在此输入图像描述

布局XML(实际上会有一个FrameLayout在哪里,EditText并且EditText将在其中):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Input"
        android:layout_gravity="center"
        android:layout_centerVertical="true"/>

    <android.support.design.widget.BottomNavigationView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:itemBackground="@color/colorPrimary"
        app:menu="@menu/menu_bottom_navigation"
        app:itemIconTint="@android:color/white"
        app:itemTextColor="@android:color/white"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

sab*_*AVA 46

将其添加到清单中的活动中

android:windowSoftInputMode="adjustPan"
Run Code Online (Sandbox Code Playgroud)

所以喜欢

<activity android:name=".feature.home.HomeActivity" 
 android:windowSoftInputMode="adjustPan"/>
Run Code Online (Sandbox Code Playgroud)

  • 问题中明确提到如何使用 adjustmentResize 而不是使用 adjustmentPan 来做到这一点。 (11认同)
  • 这不是底部导航的解决方案。 (4认同)
  • 这是一件好事,可以在打开键盘时将底部导航视图保持在底部,但不允许滚动视图起作用。 (3认同)

gpr*_*our 6

解决方案(或另一种方法)

我经历过与 OP 所说的完全相同的情况,我BottomNavigationView显然在屏幕底部有一个ScrollView.

现在,如果我们adjustPan在活动中进行,则BottomNavigationView在键盘出现时保持在底部,但滚动不起作用。

如果我们这样做,adjustResize那么滚动会起作用,但BottomNavigationView 会被推到键盘顶部。

我认为下面可以是相同的两种方法。

方法一

只需在键盘显示/隐藏时将可见性设置为消失/可见。它可以快速解决相同的问题。您可以在下一个方法中获得键盘隐藏/显示事件的监听器。

为了使它看起来有趣,您可以尝试使用某种动画显示/隐藏 BottomNavigationView。

方法二

一些更好的方法(材料设计方法)将使用CoordinatorLayout和滚动行为(与您可能已经看到的相同CollapsingToolBar)。

下面是布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:title="@string/title"
            app:titleTextColor="@android:color/white" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

    ------ Your Contents --------

    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="?android:attr/windowBackground"
        app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
        app:menu="@menu/navigation" />
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

就是这样,现在您可以看到 BottomNavigationView 在滚动到底部和顶部等时隐藏/显示。但是您可能会面临另一个问题,即在隐藏键盘时,如果内容太小而无法滚动,

问题是,当键盘打开并且您滚动到隐藏底部导航视图的底部时,现在如果您按下后退按钮键盘会隐藏但底部导航视图仍然隐藏。现在,由于内容不可滚动,因此如果您尝试滚动,它不会显示 BottomNavigationView。要再次显示它,您需要做的是,再次使键盘可见,然后向上滚动,当显示 BottomNavigationView 时,然后按后退按钮。

我试图通过这种方式解决这个问题,

添加全局侦听器以查明键盘是显示还是隐藏。我在这里使用的代码是,(它在 Kotlin 中,但是如果需要,您可以轻松地将其转换为 Java 版本)

private fun addKeyboardDetectListener(){
    val topView = window.decorView.findViewById<View>(android.R.id.content)
    topView.viewTreeObserver.addOnGlobalLayoutListener {
        val heightDifference = topView.rootView.height - topView.height
        if(heightDifference > dpToPx(this, 200F)){
            // keyboard shown
            Log.d(TAG, "keyboard shown")
        } else {
            // keyboard hidden
            Log.d(TAG, "keyboard hidden")
            val behavior = (navigation.layoutParams as CoordinatorLayout.LayoutParams).behavior as HideBottomViewOnScrollBehavior
            behavior.slideUp(navigation)
        }
    }
}

fun dpToPx(context: Context, valueInDp: Float) : Float{
    val displayMetrics = context.resources.displayMetrics
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, displayMetrics)
}
Run Code Online (Sandbox Code Playgroud)

最后一件事,如果您使用支持库版本 28.0.0,那么您将看到该 behavior.slideUp(navigation)方法受到保护,因此您无法从您的活动等中调用它。

然而,谷歌的 Android 团队已经在新的material-components. 检查这一点,以便在您的项目中导入材料组件并改用此类。

除此之外,您可以尝试更多的实验,例如在键盘隐藏/显示等上以编程方式调用 slideUp 或 slideDown。

PS 我花了很多时间来研究这种完全有效的方法,所以想在这里分享它,这样可以节省一些人的时间。


Cha*_*ruක -4

作为您的替代android:windowSoftInputMode="adjustResize"方法,您可以尝试这个。

从您的系统中调用此方法OnCreate- 一旦键盘打开,您就可以更改不需要显示的视图的可见性!当键盘按下时再次显示它们。

 public void checkKeyBoardUp(){
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                rootView.getWindowVisibleDisplayFrame(r);
                int heightDiff = rootView.getRootView().getHeight() - (r.bottom - r.top);

                if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
                    //ok now we know the keyboard is up...
                    whatEverView.setVisibility(View.INVISIBLE);

                }else{
                    //ok now we know the keyboard is down...
                    whatEverView.setVisibility(View.VISIBLE);
              }
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

  • 最好尝试使用“View.GONE”而不是“View.INVISIBLE” (3认同)
  • 这不起作用:空白留在导航栏的位置 (2认同)