DialogFragment is always resized when soft keyboar

2020-06-22 08:36发布

I'm having some issues with an custom DialogFragment that is displayed Fullscreen. This dialog has content that is scrollable and has an autocompletetextview.

Initially the dialog is displayed with an margin at the top - set programmatically as an transparent view at the top of the layout content. As soon as the autocompletetextview is focused, this margin is reduced to 0 (thus giving the illusion that the dialog is getting in fullscreen mode). At this moment the keyboard is also showed.

Currently, the keyboard reduced the size of the dialog and an button that is on the dialog is moved up, above the keyboard. This creates an issue, because as soon as the autocompletetextview looses focus, the dialog is resized and because of the keyboard resize also an flicker is created: they keyboard is hidden -> the dialog is moved at the bottom -> the dialog resizes to fullscreen -> the dialog resisez to initial size

Current creation of the dialog:

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);

        dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);

        if (!hasTitle()) {
            dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        }

        // the content
        //final RelativeLayout root = new RelativeLayout(getActivity());
        //root.setLayoutParams(
        //        new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        //dialog.setContentView(root);

        if (position != null) {
            WindowManager.LayoutParams windowParams = dialog.getWindow().getAttributes();
            windowParams.x = position.x;
            windowParams.y = position.y;
            dialog.getWindow().setAttributes(windowParams);
        } else {
            dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        }

        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(hasTitle() ? Color.WHITE : Color.TRANSPARENT));
        dialog.getWindow().setGravity(Gravity.TOP | Gravity.START);

        return dialog;
    }

This works partially, as the dialog is not filling the width, it is a lot smaller.

Something does fix this, but it creates another issue:

@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_DeviceDefault_DialogWhenLarge_NoActionBar);
    }

But this will affect how the background of the dialog looks like and I can't seem to be able to change it from the dialog creation method.

2条回答
Viruses.
2楼-- · 2020-06-22 09:00

You can do one thing for this...

Add this in your onViewCreated:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
super.onViewCreated(view, savedInstanceState);

}

Using "adjustPan" The activity's main window is not resized to make room for the soft keyboard So in this case all views of your fragment page should be in ScrollView or user may need to close the soft keyboard to get at and interact with obscured parts of the window.

Hope this will help you.

查看更多
我命由我不由天
3楼-- · 2020-06-22 09:22

I have finally found an solution to my problem.

The creation of the dialog:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);

    if (!hasTitle()) {
        dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    }

    if (position != null) {
        WindowManager.LayoutParams windowParams = dialog.getWindow().getAttributes();
        windowParams.x = position.x;
        windowParams.y = position.y;
        dialog.getWindow().setAttributes(windowParams);
    } else {
        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
        attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
        dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    }

    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(hasTitle() ? Color.WHITE : Color.TRANSPARENT));
    dialog.getWindow().setGravity(Gravity.TOP | Gravity.START);

    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);    

    return dialog;
}

The creation of the fragment (i customize the style of the dialog - it is very important to use No_FRAME):

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // We customize the style of this dialog - we remove the frames of the dialogs and leave the drawing to the
    // onCreateView() method, and we use the custom theme for dialogs - this is a special theme which has no
    // Background and the status bar is left unchanged
    setStyle(DialogFragment.STYLE_NO_FRAME, R.style.Theme_Dialog);
}

The custom theme (I reuse all my styles, so that the dialog looks the same):

<!-- Custom theme for dialogs - this will use the same styling as the main theme, but will disable the background
 of the window, and it will also leave the status bar color unchanged -->
<style name="Theme.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <!-- We do not want to change the status bar color -->
    <item name="colorPrimaryDark">@color/transparent</item>
</style>

Now my dialog fragment looks like it is FullScreen and it doesn't resize anymore when the soft keyboard is opened, thus creating the flickering effect when manually changing it's size. The important piece was the DialogFragment.STYLE_NO_FRAME.

I hope this will help others with similar problems.

查看更多
登录 后发表回答