[英]Correctly retaining listeners on orientation changes
请考虑以下情形:
Activity
,单击时会启动DialogFragment
DialogFragment
有一个侦听器interface
, Activity
提供了一个实现。 比如说, Activity
是一个图像编辑器, DialogFragment
选择一个对比 - 该对话框将有一个OnContrastChangedListener
,该Activity
实现 Activity
已实现此interface
以在其UI中更新视图。 继续使用图像编辑器示例, Activity
实现了OnContrastChangedListener
来更新其预览视图 - 如下所示:
contrastDialog.setOnContrastChangedListener(new OnContrastChangedListener { @Override public void OnContrastChanged(int newContrast) { getPreviewView().updateWithContrast(newContrast); } });
方向已更改,所有内容都将重新创建,并且使用此处推荐的方法正确保存和恢复侦听器(侦听器保存在Fragment
并在生命周期恢复状态时恢复)。
问题是监听器接口现在不起作用 。 函数getPreviewView()
现在返回null
即使在Activity
其他任何地方调用它时它返回正确的值
请原谅可怜的术语(我在编译和字节码方面的知识有限),但我能掌握所发生的事情。 该接口已使用getPreviewView()
版本进行编译,该版本返回了在方向更改时销毁的预览视图,此后已发布/垃圾收集/现在为null
。
我的问题是,在Java中是否有一种方法可以使接口编译期望值/函数发生变化 - 就像C中的volatile
关键字(我期待没有)? 在这种情况下,解决这种情况的最佳方法是什么? 我考虑过以下几点:
Activity
时重新运行的代码中创建
DialogFragment
(及其
interface
)。
OnClickListeners
for
Buttons
这样的东西
OnClickListeners
,因为它们肯定是创建的。
DialogFragment
仅在按下按钮时创建,因此这种方法意味着每次
Activity
时都会创建屏幕的每个对话框 - 这看起来很浪费,因为它们甚至可能无法运行
Activity
创建所有可能的
interfaces
并将它们保存在成员变量中,然后在请求由事件创建
DialogFragments
时使用这些
interfaces
。
interface
,以防它运行。
interfaces
的重新创建。 Hacky并在Activity
和DialogFragment
之间创建了一个平局,这不是很好的做法。 如您所见,所有选项都涉及在某种程度上浪费的娱乐 - 有没有办法重用现有的interface
实现?
编辑:选项1和2不起作用,因为它们需要指向现有Dialog
的链接。 这一切都是可行的但它越来越倾向于使用“当前Dialog”变量的黑客共同选项,在重新启动活动时使用FragmentManager
获取DialogFragment
,根据“当前Dialog”变量适当地转换它,重新创建监听器。 有一种不那么混乱的方式吗?
onAttach
onDetach
方法很好,我喜欢使用它,有时,当我知道代码中会有更多的开发人员我甚至不会盲目地使用它,但我做了这样的检查:
if(activity instanceof MyInterface){
interface = (MyInterface) activity;
} else{
thrown new RuntimeException("Dear colleague, this fragment was meant to have the activity implementing MyInterface or else a bunch of other stuff won't work, please go back to your code and add the interface");
}
但作为一种不同的手段,您还可以在重新创建片段时重新设置界面。 例如,关于onCreate
的活动
if(savedInstanceState != null){
mDialogFrag = getSupportFragmentManager().findFragmentByTag(MyDialogFrag.TAG);
if(mDialogFrag != null)
mDialogFrag.setListener(... the interface ...);
}
我知道这也不是对象的最佳分离,但事实是getPreviewView()
需要当前活动才能正常运行,因此当你重建所有人时,你需要再次传递这个引用。
这些只是不同的方式。
如果活动将始终具有接口的实现,是否可以在DialogFragment的onAttach()中设置监听器? 这将确保在销毁和重新创建时,它将具有最新的参考,例如:
public void onAttach(Activity activity) {
super.onAttach(activity);
contrastChangedListener = (OnContrastChangedListener)activity;
}
public void onDetach() {
super.onDetach();
contrastChangedListener = null;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.