使用betterpickers库时,如何获取无返回值(void)方法的结果?
解决betterpickers异步回调获取选中日期的问题
嘿,这个问题我熟!betterpickers这类日期选择库用的都是异步回调模式——用户选择日期是一个需要交互的操作,picker()方法调用后会立刻返回,根本等不及用户选完日期,所以它设计成void类型很合理。不过咱们完全可以通过类内部的状态存储+getter方法,甚至自定义监听器来获取最终选中的日期,具体方案如下:
方案1:成员变量存储+Getter方法
这是最直接的方式,在你的Inflate类里加一个成员变量保存选中的日期,然后在回调方法里赋值,最后提供一个公共方法让外部获取结果:
public class Inflate implements CalendarDatePickerDialogFragment.OnDateSetListener { private static final String FRAG_TAG_DATE_PICKER = "fragment_date_picker_name"; // 用成员变量存储用户选中的日期 private Calendar selectedDate; public void picker(FragmentManager supportFragmentManager) { CalendarDatePickerDialogFragment cdp = new CalendarDatePickerDialogFragment() .setOnDateSetListener(this); // 将当前类作为回调监听器 cdp.show(supportFragmentManager, FRAG_TAG_DATE_PICKER); } // 实现回调接口,把选中的日期存入成员变量 @Override public void onDateSet(CalendarDatePickerDialogFragment dialog, int year, int monthOfYear, int dayOfMonth) { selectedDate = Calendar.getInstance(); selectedDate.set(year, monthOfYear, dayOfMonth); // 到这里,selectedDate就已经有用户选中的日期了 } // 提供公共Getter方法,让外部获取选中的日期 public Calendar getSelectedDate() { return selectedDate; } }
使用方式:
当你创建Inflate实例并调用picker()后,等用户完成日期选择,就可以通过yourInflateInstance.getSelectedDate()拿到结果。注意要确保在用户选择完成后再调用这个方法,不然会得到null。
方案2:自定义监听器(推荐,实时通知)
如果需要在用户选中日期的第一时间就通知外部代码处理,那可以给Inflate类加一个自定义监听器,这样不用主动去调用getter,而是被动接收回调:
public class Inflate implements CalendarDatePickerDialogFragment.OnDateSetListener { private static final String FRAG_TAG_DATE_PICKER = "fragment_date_picker_name"; // 自定义监听器接口,用于通知外部日期选中事件 public interface OnDateSelectedCallback { void onDatePicked(Calendar selectedDate); } private OnDateSelectedCallback dateCallback; public void picker(FragmentManager supportFragmentManager) { CalendarDatePickerDialogFragment cdp = new CalendarDatePickerDialogFragment() .setOnDateSetListener(this); cdp.show(supportFragmentManager, FRAG_TAG_DATE_PICKER); } // 设置外部监听器的方法 public void setOnDateSelectedCallback(OnDateSelectedCallback callback) { this.dateCallback = callback; } @Override public void onDateSet(CalendarDatePickerDialogFragment dialog, int year, int monthOfYear, int dayOfMonth) { Calendar selectedDate = Calendar.getInstance(); selectedDate.set(year, monthOfYear, dayOfMonth); // 通知外部监听器日期已选中 if (dateCallback != null) { dateCallback.onDatePicked(selectedDate); } } }
使用方式:
Inflate datePicker = new Inflate(); datePicker.setOnDateSelectedCallback(new Inflate.OnDateSelectedCallback() { @Override public void onDatePicked(Calendar selectedDate) { // 在这里直接处理选中的日期,比如显示到TextView里 textView.setText(selectedDate.getTime().toString()); } }); datePicker.picker(getSupportFragmentManager());
为什么不能直接从void方法返回?
因为日期选择是异步操作,picker()方法只是负责弹出选择框,之后代码会继续往下执行,而用户选择日期需要时间,所以在picker()执行完毕时,用户还没选日期,自然没法返回结果。这种场景下,回调模式是标准的解决方案。
内容的提问来源于stack exchange,提问作者Woton Sampaio
相关产品推荐
相关产品推荐

