How to prevent custom DialogFragment from hiding keyboard when being shown

android, android-dialogfragment, android-softkeyboard

Solution

After day of experiment, I found out a solution!

Overwrite both `onCreateDialog` and `onCreateView`. Store view created at `onCreateDialog` in a member variable, and let `onCreateView` return that member variable.

Reference: https://stackoverflow.com/a/51530917/72437

Here's the complete code.

public class ColorDialogFragment extends DialogFragment {
    private View view;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private ColorFragmentPagerAdapter colorFragmentPagerAdapter;

    public static ColorDialogFragment newInstance() {
        ColorDialogFragment colorDialogFragment = new ColorDialogFragment();
        return colorDialogFragment;
    }

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

    @Override
    public void onResume() {
        super.onResume();
        getDialog().getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);


        // TODO: Read from WeNoteOptions.
        final int position = 0;
        this.viewPager.setCurrentItem(position);
        updateButtonVisibility(position);
    }

    private View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container) {
        View view = inflater.inflate(R.layout.color_dialog_fragment, container, false);

        this.tabLayout = view.findViewById(R.id.tab_layout);
        this.viewPager = view.findViewById(R.id.view_pager);
        this.colorFragmentPagerAdapter = new ColorFragmentPagerAdapter(this.getChildFragmentManager());
        this.viewPager.setAdapter(this.colorFragmentPagerAdapter);
        this.tabLayout.setupWithViewPager(this.viewPager);

        this.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                updateButtonVisibility(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        return view;
    }

    private void updateButtonVisibility(int position) {
        if (position == 1) {
            ((AlertDialog)getDialog()).getButton(DialogInterface.BUTTON_POSITIVE).setVisibility(View.VISIBLE);
        } else {
            ((AlertDialog)getDialog()).getButton(DialogInterface.BUTTON_POSITIVE).setVisibility(View.INVISIBLE);
        }
    }

    // https://stackoverflow.com/questions/20303865/viewpager-in-dialogfragment-illegalstateexception-fragment-does-not-have-a-vi
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return this.view;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        LayoutInflater layoutInflater = getActivity().getLayoutInflater();
        this.view = onCreateView(layoutInflater, null);
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity())
                .setTitle(R.string.select_a_color)
                .setView(this.view)
                .setPositiveButton(R.string.select_color, (dialogInterface, i) -> {

                });
        return alertDialogBuilder.create();
    }
}

Problem

There are 2 ways to create custom dialog via `DialogFragment`. - Overwrite `onCreateDialog` and return a dialog using `AlertDialog.Builder`. - Overwrite `onCreateView`. We notice that, if we overwrite `onCreateDialog`, the previous shown soft keyboard will not be hidden. However, if we overwrite `onCreateView`, the previous shown soft keyboard will be hidden. onCreateDialog will not hide soft keyboard onCreateView will hide soft keyboard Hiding soft keyboard is not our desired behavior. We want the soft keyboard to remain same as it is. However, we are not able to use `onCreateDialog` way, due to the limitation mentioned ViewPager in DialogFragment - IllegalStateException: Fragment does not have a view . In nutshell, if you need `ViewPager` to work well in dialog, you cannot implement custom dialog using `onCreateDialog`. If we use `onCreateView`, we can achieve everything desired, except "not hiding soft keyboard". Do you have any idea why overwrite `onCreateView` to create custom dialog, will hide the keyboard? How can we prevent such behavior? Code My dialog style is: ``` <style name="CustomDialog" parent="@style/Theme.AppCompat.Light.Dialog"> <item name="android:windowNoTitle">false</item> </style> ``` ColorDialogFragment.java: ``` public class ColorDialogFragment extends DialogFragment { private TabLayout tabLayout; private ViewPager viewPager; private ColorFragmentPagerAdapter colorFragmentPagerAdapter; public static ColorDialogFragment newInstance() { ColorDialogFragment colorDialogFragment = new ColorDialogFragment(); // We provide custom style, because we need title. colorDialogFragment.setStyle(DialogFragment.STYLE_NORMAL, R.style.CustomDialog); return colorDialogFragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onResume() { super.onResume(); getDialog().getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); } private View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container) { View view = inflater.inflate(R.layout.color_dialog_fragment, container, false); this.tabLayout = view.findViewById(R.id.tab_layout); this.viewPager = view.findViewById(R.id.view_pager); this.colorFragmentPagerAdapter = new ColorFragmentPagerAdapter(this.getChildFragmentManager()); this.viewPager.setAdapter(this.colorFragmentPagerAdapter); this.tabLayout.setupWithViewPager(this.viewPager); return view; } // We overwrite onCreateView because ViewPager in DialogFragment, can hardly play well with // onCreateDialog + AlertDialog.Builder. // // https://stackoverflow.com/questions/20303865/viewpager-in-dialogfragment-illegalstateexception-fragment-does-not-have-a-vi @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return onCreateView(inflater, container); } // We overwrite onCreateDialog, because we need title. @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.setTitle(R.string.select_a_color); return dialog; } } ```

Original source

Related problems