如何防止自定义DialogFragment在显示时隐藏键盘 [英] How to prevent custom DialogFragment from hiding keyboard when being shown

查看:469
本文介绍了如何防止自定义DialogFragment在显示时隐藏键盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There are 2 ways to create custom dialog via DialogFragment.

  1. 覆盖onCreateDialog并使用AlertDialog.Builder返回对话框.
  2. 覆盖onCreateView.
  1. Overwrite onCreateDialog and return a dialog using AlertDialog.Builder.
  2. Overwrite onCreateView.

我们注意到,如果我们覆盖onCreateDialog,则先前显示的软键盘将不会被隐藏.

We notice that, if we overwrite onCreateDialog, the previous shown soft keyboard will not be hidden.

但是,如果我们覆盖onCreateView,则先前显示的软键盘将被隐藏.

However, if we overwrite onCreateView, the previous shown soft keyboard will be hidden.

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

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.

如果使用onCreateView,则除了不隐藏软键盘"以外,我们都能实现所需的所有功能.

If we use onCreateView, we can achieve everything desired, except "not hiding soft keyboard".

您是否知道为什么覆盖onCreateView来创建自定义对话框,会隐藏键盘?我们如何防止这种行为?

Do you have any idea why overwrite onCreateView to create custom dialog, will hide the keyboard? How can we prevent such behavior?

我的对话框样式是:

<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;
    }
}

推荐答案

经过一天的实验,我找到了解决方案!

After day of experiment, I found out a solution!

覆盖onCreateDialogonCreateView.将在onCreateDialog创建的视图存储在成员变量中,然后让onCreateView返回该成员变量.

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

参考: https://stackoverflow.com/a/51530917/72437

这是完整的代码.

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();
    }
}

这篇关于如何防止自定义DialogFragment在显示时隐藏键盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆