Nach dem Update auf das neueste Support-Repository
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'
Ich bekomme die seltsame Ausnahme.
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)
In meiner BaseActivity -Klasse habe ich ein wiederverwendbares Fragment erstellt, das in der Aktivitätsklasse verwendet werden kann und die BaseActivty erweitert.
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");
}
Zurück zum MainActivty Ich habe das Fragment so benutzt,
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);
}
}
Die DialogNew Klasse befindet sich unten,
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: Der gleiche Code funktioniert mit älterem Support-Repository.
Der Fehler ist nicht besonders seltsam. Wenn Sie diesen Fehler vorher nicht erhalten haben, war das seltsam.
Android zerstört und erstellt Fragmente als Teil einer Konfigurationsänderung (z. B. Bildschirmrotation) und, falls erforderlich, eine Aufgabe (z. B. wechselt der Benutzer zu einer anderen App, der Prozess Ihrer App wird im Hintergrund beendet, danach der Benutzer) versucht, innerhalb von etwa 30 Minuten zu Ihrer App zurückzukehren). Android hat keine Möglichkeit, eine anonyme Unterklasse von DialogNew
neu zu erstellen.
Erstellen Sie daher eine normale public
-Java-Klasse (oder eine public
static
-geschachtelte Klasse), die DialogNew
erweitert und über Ihre Geschäftslogik verfügt. Sie ersetzt die anonyme Unterklasse von DialogNew
, die Sie derzeit verwenden.
Bearbeiten: Möglicherweise möchten Sie das nicht tun ... Siehe die Kommentare.
Das Codebeispiel sieht ähnlich aus, was ich über hier vorgeschlagen hatte, und ich entdeckte kürzlich auch, dass die Lösung, die ich dort hatte, nicht mehr funktionierte. Ich habe meine Antwort dort für Java7 aktualisiert, aber wenn Sie Java8 haben, ist die Lösung sehr einfach:
(Ich habe das noch nicht getestet)
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;
}
}
Dann in der Haupttätigkeit:
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);
}
}