使用键盘上方的EditText显示整个底部工作表

问题描述 投票:7回答:5

我正在实现一个UI,其中一个底部工作表将出现在键盘上方,并带有一个EditText,供用户输入一个值。问题是视图被键盘部分重叠,覆盖了底部的底部。

这是底部表,没有键盘。

Bottom Sheet

这是底部表格,键盘显示。

enter image description here

确保显示整个底板的最佳方法是什么?

谢谢。

android android-layout android-softkeyboard bottom-sheet
5个回答
9
投票

只是从这个问题Keyboard hides BottomSheetDialogFragment重新发布@jblejder,因为它对我有用,让其他人更容易找到:

我发现改变它的最方便的方法是创建样式:

<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="android:windowIsFloating">false</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowSoftInputMode">adjustResize</item>
</style>

并在BottomSheetDialogFragment的onCreate方法中设置它:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogStyle)
}

这是它在我的设备上的外观:

enter image description here


4
投票
dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);  
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    BottomSheetDialog d = (BottomSheetDialog) dialog;
                    FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
                    BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
                    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                }
            },0);
        }
    });

这段代码在Fragment的onCreateView方法中运行正常(感谢ADM)


3
投票

一个BottomSheetDialog可以帮助这个。它将打开,软键盘打开,重点是编辑文本。但用户仍然可以关闭软键盘,对话框将重置为底部。再次聚焦将使对话框出现在Softkeyboard的顶部。

 public void showDialog()  {
    final BottomSheetDialog dialog=new BottomSheetDialog(this);
    dialog.setContentView(R.layout.item_dialog);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    dialog.show();
}

您可以通过键盘扩展BottomSheetDialog。但为此你需要在SoftKeyboard Open之后调用它。扩展代码是。

 BottomSheetDialog d = (BottomSheetDialog) dialog;
            FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
            BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);

我已经在DialogInterface.OnShowListener()上测试了它,但它不起作用。测试1秒延迟其工作。但延迟不是解决方案。您需要确定应该在哪个操作上展开对话框。

 final BottomSheetDialog dialog=new BottomSheetDialog(this);
    dialog.setContentView(R.layout.item_dialog);
    dialog.getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            FrameLayout bottomSheet = (FrameLayout) dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
            BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
        }
    },2000);
    dialog.show();

1
投票

为此,我发现AlertDialog工作得最好。虽然它不会与屏幕的底部或侧面齐平,但它看起来仍然足够好。

首先,用你的视图创建AlertDialog

val view = LayoutInflater.from(context).inflate(R.layout.alert, null)

dialog = AlertDialog.Builder(context)
             .setView(view)
             .create()

接下来,设置重力。

    dialog.window.attributes.gravity = Gravity.BOTTOM

最后,展示它。

dialog.show()

您还可以使用onDismissListener绑定键盘以保持对话框。

显示AlertDialog后,我强行键盘。

调用此方法,传入EditText

fun showKeyboard(view: View?) {
        if (view == null) return;

        val imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
    }

并在onDismissListener内解雇。

private fun hideKeyboard() {
        val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
    }

1
投票

这可能是一个多余的答案。虽然只是指出了这个问题。如果您正在使用BottomSheetDialogFragment,唯一的方法是启用属性android:windowIsFloating为true。这将使整个窗口位于试图占据其背后的空间的顶部。

<style name="BottomSheetDialogThemeNoFloating" parent="Theme.Design.Light.BottomSheetDialog">
        <item name="android:windowIsFloating">false</item>
        <item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>

然后在对话框的onCreate()中设置此样式。

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // set the window no floating style
        setStyle(DialogFragment.STYLE_NORMAL, R.style.AppRoundedBottomSheetDialogThemeNoFloating)
}

这对于那些经常使用底页并且可能想要处理互相重叠的EditText和软键盘的人来说非常方便。

注意:mikepenz的类KeyboardUtil存在一个问题,即在某些手机上,尽管为所提供的整个内容视图提供了底部填充,但带有输入字段的内容视图会自动推到键盘上方。


0
投票

我的回答可能对仍在寻找解决方案的人有用。如果键盘覆盖了BottomSheetDialogFragment中的edittext,那么在setupDialog()方法中创建一个类KeyboardUtil的实例并传递你的rootview。

    @Override
    public void setupDialog(final Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View view = View.inflate(getActivity(), R.layout.reopen_dialog_layout, null);
        new KeyboardUtil(getActivity(), view);
}

创建一个新类

    public class KeyboardUtil {
        private View decorView;
        private View contentView;
        //a small helper to allow showing the editText focus
        ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                //r will be populated with the coordinates of your view that area still visible.
                decorView.getWindowVisibleDisplayFrame(r);

                //get screen height and calculate the difference with the useable area from the r
                int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                int diff = height - r.bottom;

                //if it could be a keyboard add the padding to the view
                if (diff != 0) {
                    // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                    //check if the padding is 0 (if yes set the padding for the keyboard)
                    if (contentView.getPaddingBottom() != diff) {
                        //set the padding of the contentView for the keyboard
                        contentView.setPadding(0, 0, 0, diff);
                    }
                } else {
                    //check if the padding is != 0 (if yes reset the padding)
                    if (contentView.getPaddingBottom() != 0) {
                        //reset the padding of the contentView
                        contentView.setPadding(0, 0, 0, 0);
                    }
                }
            }
        };

        public KeyboardUtil(Activity act, View contentView) {
            this.decorView = act.getWindow().getDecorView();
            this.contentView = contentView;

            //only required on newer android versions. it was working on API level 19
            if (Build.VERSION.SDK_INT >= 19) {
                decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
            }
        }

        /**
         * Helper to hide the keyboard
         *
         * @param act
         */
        public static void hideKeyboard(Activity act) {
            if (act != null && act.getCurrentFocus() != null) {
                InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
            }
        }

        public void enable() {
            if (Build.VERSION.SDK_INT >= 19) {
                decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
            }
        }

        public void disable() {
            if (Build.VERSION.SDK_INT >= 19) {
                decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.