根据material design spec,键盘出现时,BottomNavigationView
应隐藏在其下方。但是,如果我在活动清单中设置android:windowSoftInputMode="adjustResize"
,则BottomNavigationView
会移动到键盘上方。
我需要设置adjustResize
以便在键盘打开时滚动到屏幕底部。但是,我不希望BottomNavigationView
可见。可以这样做吗?
目前看起来如何:
布局XML(实际上FrameLayout
位于EditText
,EditText
位于其中{/ p>}:
<?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>
答案 0 :(得分:41)
将此添加到清单
中的活动中android:windowSoftInputMode="adjustPan"
所以喜欢
<activity android:name=".feature.home.HomeActivity"
android:windowSoftInputMode="adjustPan"/>
答案 1 :(得分:1)
在清单中添加以下行:android:windowSoftInputMode =“ adjustPan”
<activity
android:name=".main.MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
答案 2 :(得分:0)
还有另一种解决方案,它不需要adjustSpan
,但它仅适用于API >= 21
。您可以通过跟踪系统插件来检测键盘是否显示/隐藏。假设你有BottomNavigationView
,它是LinearLayout
的孩子,你需要在显示键盘时隐藏它:
> LinearLayout
> ContentView
> BottomNavigationView
您需要做的就是以这种方式扩展LinearLayout
:
public class KeyboardAwareLinearLayout extends LinearLayout {
public KeyboardAwareLinearLayout(Context context) {
super(context);
}
public KeyboardAwareLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public KeyboardAwareLinearLayout(Context context,
@Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public KeyboardAwareLinearLayout(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; index++) {
View view = getChildAt(index);
if (view instanceof BottomNavigationView) {
int bottom = insets.getSystemWindowInsetBottom();
if (bottom >= ViewUtils.dpToPx(200)) {
view.setVisibility(GONE);
} else {
view.setVisibility(VISIBLE);
}
}
}
return insets;
}
}
这个想法是,当显示键盘时,系统插入更改的值很大.bottom
。
答案 3 :(得分:0)
我经历了与OP所述完全相同的情况,很明显,我在屏幕底部有BottomNavigationView
。在上面有ScrollView
。
现在,如果我们在活动中进行
adjustPan
,则BottomNavigationView
会在出现键盘时停留在底部,但滚动不起作用。如果我们执行
adjustResize
,则可以滚动,但BottomNavigationView会被推到键盘顶部。
我认为以下是相同的两种方法。
方法1
只需在键盘显示/隐藏上将可见性设置为“消失” /“可见”即可。同样,它也可以快速解决。您可以通过下一种方法自行获取键盘隐藏/显示事件的侦听器。
为使它看起来有趣,您可以尝试使用某种动画显示/隐藏BottomNavigationView。
方法2
一些更好的方法(材料设计方法)将使用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>
就是这样,现在您可以看到BottomNavigationView隐藏/显示在滚动到底部和顶部等。但是在一种情况下,您可能会遇到另一个问题,即当内容隐藏时,如果键盘太小,则无法滚动,
问题是,当键盘打开并滚动到底部时,它会隐藏BottomNavigationView,现在,如果您按“后退”按钮,键盘将隐藏,但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)
}
最后,如果您使用支持库版本28.0.0,那么您将看到behavior.slideUp(navigation)
方法受到保护,因此您无法从活动等中调用它。
但是,Google的Android团队已经在新的material-components
中公开了这些方法。 Check this,因此只需在您的项目中导入材料组件并使用此类即可。
除此之外,您还可以尝试其他一些实验,例如以编程方式在隐藏/显示键盘上调用slideUp或slideDown等。
P.S。我花了很多时间来使用这种完全有效的方法,因此想在这里分享它,这样可以节省别人的时间。
答案 4 :(得分:-1)
有时会发生这种情况从其他布局复制粘贴。在我的情况下,我只是从布局文件中删除 tools:context="Your class name"
。谢谢