AlertDialog按键后不取消对话框实现方式

AlertDialog按键后不取消对话框实现方式

我们在使用默认Android对话框的上的按键时,当我们按下后,对话框就会自动关闭,但有时某些需求需要我们通过对话框进行与界面进行交互,而不是立即关闭,我们如何实现呢?先看下图吧!

如图Dialog使用了DatePicker和TimePicker,将按键设置日期和时间(2016年9月9日 上午 9点09),这里我设置完日期后还需要提供设置时间,如果把日期和时间弄到一个界面效果不太理想,于是我们通过Dialog上按钮进行切换

实现方法

AlertDialog提供三种positive按钮、negative按钮以及neutral按钮

  1. 通过反射将Dialog类中的私有布尔类型成员“mShowing”修改为false

    private void canNotCloseDialog(DialogInterface dialogInterface) {
        try {
            Class<? extends DialogInterface> aClass = dialogInterface.getClass();
            Class<?> superclass = aClass.getSuperclass().getSuperclass();
            Field field = superclass.getDeclaredField("mShowing");
            field.setAccessible(true);
            field.set(dialogInterface, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
  2. (推荐)通过alertDialog.getButton()方法,拿到按键对象,设置按键侦听

    Button btNegative = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
    btNegative.setOnClickListener(new View.OnClickListener() {
        ...
    }
    

分析

这里还存在以下几个问题:

1. 这两种方法有什么区别?为什么推荐第二种?
2. 应该在什么时间使用?
  1. 问题1:这两种方法有什么区别?为什么推荐第二种?

    1. 首先方法1的核心是修改Dialog类中的私有布尔类型成员“mShowing”,谷歌并不提供这个修改该变量的方法,所以有可能在未来谷歌更新过程中,导致反射修改失效。
    2. 方法1修改后,所有按键(positive按钮、negative按钮以及neutral按钮)点击后均无法关闭对话框,不够灵活。
    3. 方法2解决了以上两个问题所以推荐
  2. 问题2:应该在什么时间使用?

    两种方法均只能在dialog显示后才能生效

    //在dialog显示侦听进行设置
    alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            //在这里处理按键不取消
            ...
        }
    }
    

代码

理论说完附上上图的关键代码

dialog_date_picker.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
>

<DatePicker
    android:id="@+id/dp_dialog"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >

</DatePicker>

<TimePicker
    android:id="@+id/tp_dialog"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="invisible"
    />
</FrameLayout>

dialog关键代码

Date date = new Date();
View view = View.inflate(getActivity(), R.layout.dialog_date_picker, null);
final DatePicker datePicker = (DatePicker) view.findViewById(R.id.dp_dialog);
final TimePicker timePicker = (TimePicker) view.findViewById(R.id.tp_dialog);

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);

timePicker.setHour(hour);
timePicker.setMinute(minute);
datePicker.init(year, month, day, null);

final AlertDialog alertDialog = new AlertDialog.Builder(getActivity())
        .setTitle(R.string.date_picker_title)
        .setView(view)
        .setNegativeButton(R.string.dialog_to_time, null)
        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    int year = datePicker.getYear();
                    int month = datePicker.getMonth();
                    int day = datePicker.getDayOfMonth();
                    int hour = timePicker.getHour();
                    int minute = timePicker.getMinute();
                    Date date = new GregorianCalendar(year,
                            month,
                            day,
                            hour,
                            minute).getTime();
                    sendResult(date);//发送结果
                    //dialog.dismiss();//如果使用方法1,需要手动关闭dialog
                }
            })
            .create();

alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialog) {
        //canNotCloseDialog(dialog);//方法1

        final Button btNegative = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
        btNegative.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isSetData) {
                    btNegative.setText(R.string.dialog_to_time);
                    datePicker.setVisibility(View.VISIBLE);
                    timePicker.setVisibility(View.INVISIBLE);
                    isSetData = false;
                } else {
                    btNegative.setText(R.string.dialog_to_date);
                    datePicker.setVisibility(View.INVISIBLE);
                    timePicker.setVisibility(View.VISIBLE);
                    isSetData = true;
                }
            }
        });
    }
});
alertDialog.setCanceledOnTouchOutside(false);

结束语

如果您觉得这篇文章能够帮助到您,请帮忙顶一下,您的鼓励是对我的最大支持
如需转载请标明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值