实际上,我只是创建了与您所询问的内容类似的对话片段。我是为一个相当大的应用程序而设计的,我们的主要活动扩展的对话侦听器的数量只是为了侦听单个对话的结果,这有点荒谬。
为了让事情变得更灵活,我转而使用 Google 的 Guava 并发库中的 ListenableFuture。
我创建了以下要使用的抽象类:
public abstract class ListenableDialogFragment<T> extends DialogFragment implements ListenableFuture<T> {
private SettableFuture<T> _settableFuture;
public ListenableDialogFragment() {
_settableFuture = SettableFuture.create();
}
@Override
public void addListener(Runnable runnable, Executor executor) {
_settableFuture.addListener(runnable, executor);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return _settableFuture.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
return _settableFuture.isCancelled();
}
@Override
public boolean isDone() {
return _settableFuture.isDone();
}
@Override
public T get() throws InterruptedException, ExecutionException {
return _settableFuture.get();
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return _settableFuture.get(timeout, unit);
}
public void set(T value) {
_settableFuture.set(value);
}
public void setException(Throwable throwable) {
_settableFuture.setException(throwable);
}
// Resets the Future so that it can be provided to another call back
public void reset() {
_settableFuture = SettableFuture.create();
}
@Override
public void onDismiss(DialogInterface dialog) {
// Cancel the future here in case the user cancels our of the dialog
cancel(true);
super.onDismiss(dialog);
}
使用这个类,我可以创建自己的自定义对话框片段并像这样使用它们:
ListenableDialogFragment<int> dialog = GetIdDialog.newInstance(provider.getIds());
Futures.addCallback(dialog, new FutureCallback<int>() {
@Override
public void onSuccess(int id) {
processId(id);
}
@Override
public void onFailure(Throwable throwable) {
if (throwable instanceof CancellationException) {
// Task was cancelled
}
processException(throwable);
}
});
这就是 GetIdDialog 是 ListenableDialogFragment 的自定义实例的地方。如果需要,我可以通过简单地在 onSuccess 和 onFailure 方法中调用 dialog.reset 来重用同一个对话框实例,以确保重新加载内部 Future 以添加回回调。
我希望这能够帮到你。
编辑:抱歉忘了添加,在您的对话框中,您可以实现一个点击监听器,它会执行以下操作来触发未来:
private class SingleChoiceListener implements DialogInterface.OnClickListener {
@Override
public void onClick(DialogInterface dialog, int item) {
int id = _ids[item];
// This call will trigger the future to fire
set(id);
dismiss();
}
}