更新到最新的支持存储库后,
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support:percent:24.2.0'
compile 'com.android.support:recyclerview-v7:24.2.0'
我得到了一个奇怪的异常。
java.lang.IllegalStateException: Fragment null must be a public static class to be properly recreated from instance state.
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:435)
at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:414)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:154)
at com.androidapp.base.BaseActivity.showDialogFragment(BaseActivity.java:78)
at com.androidapp.MainActivity.showNewDialog(MainActivity.java:304)
at com.androidapp.MainActivity$6.onClick(MainActivity.java:228)
在我的BaseActivity类中,我创建了一个可重用的片段,它可以在扩展BaseActivty的Activity类中使用
public void showDialogFragment(DialogFragment newFragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack("dialog");
newFragment.show(ft, "dialog");
}
返回到MainActivty我像这样使用了这个片段,
public class MainActivity extends BaseActivity {
@SuppressLint("ValidFragment")
public void showNewDialog(int type, String title, String message) {
final DialogNew dialog = new DialogNew() {
@Override
public void success(boolean isLandscape) {
.......
}
@Override
public void cancel() {
}
};
dialog.setArgs(title, message);
super.showDialogFragment(dialog);
}
}
DialogNew类如下所示,
public abstract class DialogNew extends DialogFragment {
private View rootView;
private String title;
private String message;
public void setArgs(String title, String message) {
Bundle args = new Bundle();
args.putString("title", title);
args.putString("message", message);
setArguments(args);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, 0);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_new_dialog, container, false);
init();
setListeners();
return rootView;
}
public abstract void success(boolean isLandscape);
public abstract void cancel();
}
PS:相同的代码适用于较旧的支持存储库。
6条答案
按热度按时间06odsfpq1#
这个错误并不是特别奇怪。如果你以前没有得到这个错误,那就很奇怪了。
作为配置更改(例如屏幕旋转)的一部分,以及在需要时重建任务的一部分(例如,用户切换到另一个应用,您的应用进程在后台终止,然后用户尝试返回您的应用,所有这些都在30分钟左右),Android会销毁并重新创建片段。Android无法重新创建
DialogNew
的匿名子类。因此,创建一个常规的
public
Java类(或public
static
嵌套类),它扩展DialogNew
并具有您的业务逻辑,替换您目前使用的DialogNew
的匿名子类。yrefmtwq2#
我重新制作了我的碎片,它为我解决了这个问题。
新建-〉片段-〉片段(空白),并在确认前取消选中第二个框。
iqxoj9l93#
Android开发人员指南中对此错误的原因进行了很好的解释。
当系统发布配置更改时,它需要能够创建片段的新示例。为此,它依赖于片段的默认构造函数,该构造函数不带参数,因此不能有任何依赖关系。如果您的Fragment类不是静态公共类,系统将无法反射地找到此默认构造函数,错误将指出这一点。
为了解决这个问题,你必须覆盖FragmentManager示例的FragmentFactory的默认实现,它将处理你的片段的创建。
khbbv19g4#
***编辑:***您可能不想这样做...请查看评论。
代码示例看起来与我在here上建议的类似,而且我最近还发现我在那里的解决方案不再起作用了。我已经更新了我在那里对Java7的回答,但是如果你有Java8,解决方案超级简单:
(我还没有测试过)
然后在主要活动中:
tvmytwxo5#
通过新建〉片段〉空白片段创建片段
这对我很有效
4nkexdtk6#
出现此错误是因为在创建片段的示例时使用了虚方法。
必须从声明中删除虚拟方法,并且应使用处理程序类来侦听DialogNew类事件。