DialogFragment timepicker onCancel 和 onDismiss 问题

Posted

技术标签:

【中文标题】DialogFragment timepicker onCancel 和 onDismiss 问题【英文标题】:DialogFragment timepicker onCancel and onDismiss problem 【发布时间】:2020-06-18 14:47:14 【问题描述】:

我尝试实现一个由 SwitchCompat 打开的时间选择器,所以当我启用该选项时,时间选择器会显示出来,它工作正常,但如果我按下取消或返回按钮,或者只是按下外部时间选择器,开关保持在 ON 位置,当我没有在 Time Picker 中选择时间时,我希望它回到 OFF 位置。认为也许 onCancel 方法可以帮助但它没有,或者只是我在实现它时犯了一些错误,有相关代码:

public class Settings extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener, TimePickerDialog.OnDismissListener, TimePickerDialog.OnCancelListener 
    private EditText textLastHour;
    private KeyListener keyListener;
    private SwitchCompat hourSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);

        textLastHour = findViewById(R.id.finalHourText);
        textLastHour.setKeyListener(null);
        textLastHour.setHint("Option not selected");

        hourSwitch = findViewById(R.id.switch_hour);

        hourSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() 
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
                if (isChecked) 
                    DialogFragment timePicker = new TimePickerFragment();
                    timePicker.show(getSupportFragmentManager(), "time picker");

                 else 
                    textLastHour.setText("");
                
            
        );
    


    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) 
        textLastHour = findViewById(R.id.finalHourText);
        textLastHour.setText("Final alarm at: " + hourOfDay + ":" + minute);
    

    @Override
    public void onCancel(DialogInterface dialog) 
        hourSwitch.setChecked(false);
    

    @Override
    public void onDismiss(DialogInterface dialog) 
        hourSwitch.setChecked(false);
    

onDismissonCancel 我都试过了,都没有在这里工作,如果取消时间选择器,有什么解决方案可以让 Switch 回到原来的位置吗?将DatePicker 添加到标签中,因为我觉得它可能具有与TimePicker 相同的解决方案。

我的TimePickerFragment班级:

public class TimePickerFragment extends DialogFragment 

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) 
        Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(), hour, minute, DateFormat.is24HourFormat(getActivity()));
    

【问题讨论】:

据我所见,当用户未设置时间时,您没有取消/关闭回调。我建议创建另一个继承自 TimePickerDialog 的类,并在对话框关闭时创建另一个回调 我将在这里添加我的 TimePickerClass 秒,是的,我对这些方法有问题,但有点不明白如何解决它们,在互联网上找到了那些 onCancel 和 onDismiss 侦听器,但是没有一个解决方案适合我 【参考方案1】:

它实际上比我想象的要简单,您需要做的就是添加一个关闭侦听器并相应地更改您的用户界面/逻辑

TimePickerDialog dialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() 
    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) 

    
, 10, 10, true);

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() 
    @Override
    public void onCancel(DialogInterface dialog) 
        Toast.makeText(MainActivity.this, "dismissed", Toast.LENGTH_LONG).show();
    
);

dialog.show();

您可以使用标准的 TimePickerDialog

编辑:把所有东西都放到onCreate() 除了dialog.show()dialog.show() 进入开关中的 ifChecked

【讨论】:

我应该在哪里添加您的代码?我有点不明白。它应该在 if(ifChecked) 中吗? 正确,如果您只想在用户打开开关/复选框时打开对话框,则代码需要在那里 非常感谢,它对我帮助很大,只需将 onDismissListener 更改为 onCancelListener,因为即使在我尝试设置时间后 onDismissListener 也会启动【参考方案2】:

正如我在您的代码中看到的,您没有在 TimePickerFragment 类中定义任何侦听器。您可以在 TimePickerFragment 中添加以下代码:

public  class TimePickerFragment(Context context) extends DialogFragment

    interface OnCompleteListener 
        abstract void onComplete(boolean suceeded);
    

    OnCompleteListener listener;

    /**

    * your other lines of code

    **/

不要忘记为您的班级设置上下文参数! 然后覆盖 onAttach 函数并在其中实现您的侦听器,如下所示:

try 
            this.listener = (OnCompleteListener) context;

         catch (ClassCastException e) 

            throw ClassCastException(activity.toString() + " must implement OnCompleteListener");

        

在此之后,在您的覆盖 onDismiss() 中并在其中设置 listener.onComplete(false);。每当 TimePickerFragment 想要成功完成时,只需设置 listener.onComplete(true); 现在我们将回到 MainActivity。首先让 MainActivity 实现TimePickerFragment.OnCompleteListener。 现在你需要重写OnCompleteListener 的抽象函数。简单地说,如果参数为假,则意味着对话框未成功关闭,因此使用简单的 if 条件以编程方式将您的 Switch 设置为关闭。 希望我能帮上忙。

【讨论】:

(上下文上下文)在类中创建错误 @PatrykLipka 我已经从 Kotlin 迁移到了 java,所以可能需要进行一些更改,但是当您添加此参数时,您应该在 MainActivity @987654328 中像这样实例化您的 TimePickerFragment 时传递您的活动@

以上是关于DialogFragment timepicker onCancel 和 onDismiss 问题的主要内容,如果未能解决你的问题,请参考以下文章

鸿蒙App开发---TimePicker组件

鸿蒙App开发---TimePicker组件

TimePicker源码学习-TimePicker的结构

TimePicker

DialogFragment: DialogFragment的一些理解

Activity与DialogFragment交互的方法