我创建了可重复使用的文本查询对话框片段。但它不处理配置。变化。片段重新创建后,mClickListener为null(如预期的那样)。问题是 - 我如何保留回调? (我是java的新手,可能不知道常见的java模式/解决方案)
public class TextQueryDialogFragment extends DialogFragment {
private OnDialogListener mClickListener;
private EditText mTextWidget;
public void setClickListener(OnDialogListener listener) {
mClickListener = listener;
}
public String getQueryText() {
return mTextWidget.getText().toString();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater factory = LayoutInflater.from(getActivity());
final View queryView = factory.inflate(R.layout.query_dialog_text, null);
mTextWidget = (EditText) queryView.findViewById(R.id.query_dialog_text);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setView(queryView)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(null != mClickListener)
mClickListener.OnPositiveClick();
dialog.dismiss();
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(null != mClickListener)
mClickListener.OnNegativeClick();
dialog.cancel();
}
});
return builder.create();
}
}
用法:
TextQueryDialogFragment dialog = new TextQueryDialogFragment();
dialog.setQueryText(mBookmarkTitle);
dialog.setClickListener(new OnDialogListener() {
@Override
public void OnPositiveClick() {
String title = dialog.getQueryText();
//do work here
}
@Override
public void OnNegativeClick() {}
});
dialog.show(getFragmentManager(), "MYTAG");
Serializable不起作用,因此onSaveInstanceState不是我需要的。 Parcelable可能会(使用aidl和IBinder)但这对于这么简单的任务来说太过分了。
到目前为止,我发现了两种或多或少不太合适的解决方案:
在创建父片段时更新回调:
TextQueryDialogFragment dialog =(TextQueryDialogFragment) 。getFragmentManager()findFragmentByTag(RENAME_TAG); if(null!= dialog){ dialog.setClickListener(getListener()); }
有没有更好的解决方案,或者那两个可以吗?
答案 0 :(得分:2)
解决方案很简单,与onRetainConfigurationInstance
或此处提到的其他技术无关。只需在重新创建父片段时在TextQueryDialogFragment
中搜索FragmentManager
实例,并在实例仍然存在的情况下再次设置侦听器。
将以下代码添加到父onCreateView
方法:
TextQueryDialogFragment retFragment =
(TextQueryDialogFragment)getFragmentManager().findFragmentByTag("MYTAG");
if(retFragment != null)
{
retFragment.setClickListener(new OnDialogListener() {
@Override
public void OnPositiveClick() {
String title = dialog.getQueryText();
//do work here
}
@Override
public void OnNegativeClick() {}
}
);
}
在这种情况下,我宁愿通过您的片段类实现onClickListener,以便您可以这样重写它:
TextQueryDialogFragment retFragment =
(TextQueryDialogFragment )getFragmentManager().findFragmentByTag("MYTAG");
if(retFragment != null)
{
retFragment.setClickListener(this);
}
答案 1 :(得分:0)
我认为您正在寻找onRetainConfigurationInstance
,您可以返回任何您想要的对象。
public Object onRetainNonConfigurationInstance() { ... }
然后你可以在onCreate()
中找到它:
if (getLastNonConfigurationInstance() != null) {
instance = (Type) getLastNonConfigurationInstance();
}
但是,我不确定为什么你需要保留OnClickListener
。
答案 2 :(得分:0)
我遇到了类似的问题,而vitakot的答案就是解决方案!但我的情况稍微复杂一点:我有一个片段'MyAttributeFragment',它使用DialogFragment进行文本输入。此MyAttributeFragment在同一个Activity中使用了多次,因此DialogFragment的静态标记(如“MYTAG”)不是唯一的。我通过获取MyAttributeFragment的ID来识别拥有的片段来解决这个问题。
//Create DialogFragment with the unique ID of the owning fragment
newFragment.show(getFragmentManager(), String.valueOf(this.getId()));