DialogFragment is always resized when soft keyboard is opened
Asked Answered
G

2

9

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.

Gnostic answered 10/6, 2016 at 10:34 Comment(0)
G
14

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.

Gnostic answered 10/6, 2016 at 12:20 Comment(3)
What a HORROR Bruv .. Believe me You save me . I have be busting my head over this from last 2 days . This answer deserve a 100 upvotes . I did not find anywhere STYLE_NO_FRAME.Puklich
Glad it helped someone, even after some years after posting it :DGnostic
thank you! I was troubled with this problem for hours. I like you! But I can not get married ... I'm sorry ...Already
T
2

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.

Twobyfour answered 10/6, 2016 at 11:17 Comment(3)
Your edited answer is the same, only that it is know programmatically set. As you could expect, the result is the same.Gnostic
Yes you are right...but in some case statically attribute definition doesn't work. So check once.Twobyfour
It didn't work setting the soft input mode programmatically only, I've also had to customize the style of the dialog to make it look like that. I've posted an answer with my solution. Still, thank you for your time and for your help.Gnostic

© 2022 - 2024 — McMap. All rights reserved.