如何防止自定义DialogFragment在被显示时隐藏键盘

6
有两种方法可以通过DialogFragment创建自定义对话框:

  1. 重写onCreateDialog,使用AlertDialog.Builder返回对话框。
  2. 重写onCreateView

我们注意到,如果我们重写了onCreateDialog,则先前显示的软键盘将不会被隐藏。

然而,如果我们重写了onCreateView先前显示的软键盘将被隐藏。

onCreateDialog不会隐藏软键盘

enter image description here


onCreateView会隐藏软键盘

enter image description here


隐藏软键盘并不是我们想要的行为。我们希望软键盘保持原样。

但是,由于在DialogFragment中使用ViewPager - IllegalStateException: Fragment does not have a view提到的限制,我们无法使用onCreateDialog的方式。简言之,如果您希望ViewPager在对话框中正常工作,则不能使用onCreateDialog实现自定义对话框。

如果我们使用onCreateView,我们可以实现所有期望的功能,除了“不隐藏软键盘”。

您有什么想法,为什么重写onCreateView创建自定义对话框会隐藏键盘?我们如何防止这种行为?


代码

我的对话框样式是:

<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://dev59.com/kuo6XIcBkEYKwwoYKRLd
    @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;
    }
}

哦,这真是一团糟,如果我们隐藏键盘,当弹出窗口出现时再打开它怎么样? :-/ - Manoj Perumarath
@ManojPerumarath 我们想要避免这种情况,因为(1)它不能提供良好的用户体验。(2)它很难实现。需要记住父组件的焦点位置/组件,并在对话框关闭时恢复回去。 - Cheok Yan Cheng
1个回答

4
经过一天的实验,我找到了一个解决方案!
重写 onCreateDialogonCreateView。将在 onCreateDialog 中创建的视图存储在成员变量中,并让 onCreateView 返回该成员变量。
参考:https://dev59.com/kuo6XIcBkEYKwwoYKRLd#51530917 以下是完整的代码。
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://dev59.com/kuo6XIcBkEYKwwoYKRLd
    @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();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接