最新のサポートリポジトリに更新した後、
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を拡張するアクティビティクラスで使用できる再利用可能なフラグメントを作成しました
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:古いサポートリポジトリでも同じコードが機能します。
エラーは特に奇妙ではありません。以前にこのエラーが発生していなかった場合、thatは奇妙でした。
Androidは、構成の変更(画面の回転など)の一部として、必要に応じてタスクの再構築の一部として(たとえば、ユーザーが別のアプリに切り替え、アプリのプロセスがバックグラウンドにある間に終了し、その後ユーザーがすべて30分以内にアプリに戻ろうとします)。 Androidには、DialogNew
の匿名サブクラスを再作成する手段がありません。
そのため、通常のpublic
Javaクラス(またはpublic
static
ネストされたクラス)を作成して、DialogNew
を拡張し、現在使用しているDialogNew
の匿名サブクラスを置き換えるビジネスロジック。
Edit:おそらくこれをしたくないでしょう..コメントを参照してください。
コードサンプルは、私が here で提案したものに似ています。また、最近、私が持っていたソリューションがもう機能していないことも発見しました。 Java7の回答を更新しましたが、Java8を使用している場合、ソリューションは非常に簡単です。
(私はまだこれをテストしていません)
public class DialogNew extends DialogFragment {
private View rootView;
private String title;
private String message;
// Do nothing by default
private Consumer mSuccess = (boolean b) -> {};
private Runnable mCancel = () -> {};
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);
// use mSuccess.accept(boolean) when needed
init();
setListeners();
return rootView;
}
public void setSuccess(Consumer success) {
mSuccess = success;
}
public void setCancel(Runnable cancel) {
mCancel = cancel;
}
}
次に、メインアクティビティで:
public class MainActivity extends BaseActivity {
public void showNewDialog(int type, String title, String message) {
final DialogNew dialog = new DialogNew();
dialog.setArgs(title, message);
dialog.setSuccess((boolean isLandscape) -> {
//....
});
super.showDialogFragment(dialog);
}
}