我正在尝试显示带有几个BottomSheetDialogFragment
字段的EditText
,供用户输入信息。我想直接在键盘上方显示它,但它会不断覆盖内容。
这是当我提出BottomSheetDialogFragment
时发生的事情,你可以看到它选择Card Number
EditText
,但覆盖其他内容。
理想情况下,这就是我正在寻找的,你可以看到EditTexts
和视图的填充。
我已经尝试了很多围绕windowSoftInputMode
的解决方案,但似乎没有任何效果。我把它设置为adjustResize
为父母Activity
和实际的BottomSheetDialogFragment
通过
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
而且我也尝试修改我的布局,将它从FrameLayout
更改为ScrollView
到CoordinatorLayout
,看看它是否对布局的位置有任何影响,但似乎没有任何效果。
如果有人知道如何做到这一点,那将非常感谢,谢谢。
以下步骤可能有助于解决您的问题。
首先在xml文件中的EditText上添加以下行
android:imeOptions="actionSend|flagNoEnterAction"
例如:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:hint="Card number"
android:imeOptions="actionSend|flagNoEnterAction"/>
然后在AndroidManifest.xml文件中的activity标记上添加以下行
android:windowSoftInputMode="stateVisible|adjustResize"
例如:
<activity android:name=".stack.MainActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
你可以从here找到有关屏幕输入法的更多细节。
我终于在键盘打开时更改了对话框的高度,并在关闭时将其调整为正常。
KeyboardVisibilityEvent库:https://android-arsenal.com/details/1/2519
KeyboardVisibilityEvent.setEventListener(activity) { isOpen ->
setDialogHeight(isOpen)
}
对于2.0.0,支持min SDK版本为14
键盘打开时将对话框高度设置为80%:
/**
* Changes size of dialog based on keyboard visibility state
*/
private fun setDialogHeight(expanded: Boolean) {
val dialog = dialog as BottomSheetDialog?
val bottomSheet =
dialog!!.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout?
val behavior = BottomSheetBehavior.from(bottomSheet!!)
val displayMetrics = activity!!.resources.displayMetrics
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels
val maxHeight = (height * 0.88).toInt()
behavior.peekHeight = if (expanded) maxHeight else -1
}
Android操作系统本身不支持向虚拟键盘添加填充,但有一些黑客方法可以使用它。
一种方法是监听edittext的焦点,并更像滚动ScrollView:
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
scrollView.scrollBy(0, 100);
});
正如我所说,这种方式很黑,不推荐。
另一种方式(取决于你的布局,如果你让它工作更好)将在AndroidManifest.xml中为你的活动设置windowSoftInputMode
到adjustPan
或adjustResize
(取决于你的布局)。
试试这个BottomSheetDialogFragment:
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialog;
import android.support.design.widget.BottomSheetDialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
public class TestBottomSheetDialog extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, container, false);
if (getDialog().getWindow() != null) {
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
if (getActivity() != null) {
View decorView = getActivity().getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
Rect displayFrame = new Rect();
decorView.getWindowVisibleDisplayFrame(displayFrame);
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int heightDifference = height - displayFrame.bottom;
if (heightDifference != 0) {
if (fragmentView.getPaddingBottom() != heightDifference) {
fragmentView.setPadding(0, 0, 0, heightDifference);
}
} else {
if (fragmentView.getPaddingBottom() != 0) {
fragmentView.setPadding(0, 0, 0, 0);
}
}
});
}
getDialog().setOnShowListener(dialog -> {
BottomSheetDialog d = (BottomSheetDialog) dialog;
View bottomSheetInternal = d.findViewById(android.support.design.R.id.design_bottom_sheet);
if (bottomSheetInternal == null) return;
BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
});
return fragmentView;
}
}
我不得不放大布局高度。来自How to change the default height of bottomsheet dialog fragment?的程序化方法没有帮助,所以我只是改变了布局。
<android.support.constraint.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"
>
<View
android:id="@+id/top_space"
android:layout_width="match_parent"
android:layout_height="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<!-- Other views -->
<View
android:id="@+id/bottom_space"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button"
app:layout_constraintVertical_weight="1"
/>
</android.support.constraint.ConstraintLayout>
也许是一个迟到的答案但可能会有帮助。
没有其他任何对我有用。但这个解决方案正在发挥作
在NestedScrollView中包装布局
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<--Rest of the layout-->
</androidx.core.widget.NestedScrollView>
内部款式:
<style name="BottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/AppModalStyle</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
<style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/rounded_corner_dialog</item>
</style>
这里android:windowIsFloating
应该是假的,android:windowSoftInputMode
必须是adjustResize