考虑以下情况:
Activity
个UI元素,点击时会启动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);
}
});
更改方向,重新创建所有内容,并使用建议的方法here正确保存和恢复侦听器(侦听器保存在Fragment
中,并在生命周期恢复状态时恢复)。
问题是现在不的监听器界面。函数getPreviewView()
现在返回null
,即使在Activity
中的任何其他位置调用它时它返回正确的值
请原谅可怜的术语(我在编译和字节码方面的知识有限),但我能掌握所发生的事情。该接口已使用getPreviewView()
版本进行编译,该版本返回了在方向更改时销毁的预览视图,此后已发布/垃圾收集/现在为null
。
我的问题是,Java中是否有一种方法可以使接口编译期望值/函数发生变化 - 就像C中的volatile
关键字一样(我希望没有)?在这种情况下,解决这种情况的最佳方法是什么?我考虑过以下几点:
DialogFragment
时重新运行的代码中创建interface
(及其Activity
)。这对OnClickListeners
Buttons
之类的内容很好,因为它们肯定是创建的。但是这个DialogFragment
仅在按下按钮时创建,所以这种方法意味着每次Activity
时都会创建屏幕的每个对话框 - 这看起来很浪费,因为它们甚至可能无法运行interfaces
创建所有可能的Activity
并将其保存在成员变量中,然后在请求创建interfaces
时使用这些DialogFragments
通过这个事件。与上面相同的评论 - 似乎浪费在创建每个可能的interface
以防万一它运行。 击> interfaces
的重新创建。 Hacky并在Activity
和DialogFragment
之间创建了一个平局,这不是很好的做法。正如您所看到的,所有选项都涉及在某种程度上浪费的娱乐 - 有没有办法重用现有的interface
实施?
编辑:选项1和2无效,因为他们需要指向现有Dialog
的链接。这一切都是可行的,但它越来越倾向于使用“当前对话框”变量的黑客共同选项,在重新启动活动时将DialogFragment
与FragmentManager
一起使用,根据'当前的Dialog'变量,重新创建监听器。是否有一种不那么混乱的方式?
答案 0 :(得分:1)
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()
需要当前活动才能正常运行,因此当每个人都被重建时,你需要再次传递这个引用。
这些只是不同的方式。
答案 1 :(得分:0)
如果活动始终具有接口的实现,是否可以在DialogFragment的onAttach()中设置监听器?这将确保在销毁和重新创建时,它将具有最新的参考,例如:
public void onAttach(Activity activity) {
super.onAttach(activity);
contrastChangedListener = (OnContrastChangedListener)activity;
}
public void onDetach() {
super.onDetach();
contrastChangedListener = null;
}