Laden Sie die Anwendung nicht neu, wenn sich die Ausrichtung ändert

152

Ich brauche einfach nichts zu ändern, wenn der Bildschirm gedreht wird. Meine App zeigt beim ersten Laden ein zufälliges Bild an, und durch Drehen des Geräts sollte kein anderes zufälliges Bild ausgewählt werden. Wie kann ich (einfach) dieses Verhalten stoppen?

Jimmy D.
quelle
1
Es ist auch möglich, die Bildschirmausrichtung über den Code zu sperren (und möglicherweise zu entsperren). Rufen Sie dazu einfach Screen.lockOrientation(this)unter github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/… an. Es ermöglicht das Entsperren, was das Manifest nicht tut.
Caw
@Escobar Ceaser Was ist die richtige Lösung für diese Frage. Auch ich habe die gleiche Anforderung.
Prabs
Ich möchte dies programmgesteuert im Code tun.
Pollaris

Antworten:

249

Es gibt im Allgemeinen drei Möglichkeiten, dies zu tun:

  1. Wie in einigen Antworten vorgeschlagen, können Sie die Fälle unterscheiden, in denen Ihre Aktivität zum ersten Mal erstellt und wiederhergestellt wurde savedInstanceState. Dies erfolgt durch Überschreiben onSaveInstanceStateund Überprüfen des Parameters von onCreate.

  2. Sie können die Aktivität in einer Ausrichtung sperren, indem Sie sie in Ihrem Manifest hinzufügen android:screenOrientation="portrait"(oder "landscape") <activity>.

  3. Sie können dem System mitteilen, dass Sie Bildschirmänderungen selbst vornehmen möchten, indem Sie android:configChanges="orientation|screenSize"im <activity>Tag angeben. Auf diese Weise wird die Aktivität nicht neu erstellt, sondern erhält stattdessen einen Rückruf (den Sie ignorieren können, da er für Sie nicht nützlich ist).

Persönlich würde ich mit (3) gehen. Wenn es für Sie in Ordnung ist, die App an eine der Ausrichtungen zu binden, können Sie natürlich auch mit (2) fortfahren.

Xion
quelle
13
Wollen Sie für # 3 nur sagen, dass ich diese Zeile zu meinem Manifest hinzufügen muss? Weil es nicht funktioniert.
Jimmy D
2
# 3 Bitte überprüfen Sie auf stackoverflow.com/questions/456211/…
Yeo
16
@EscobarCeaser, Für Android 3.2 und höher benötigen Sieandroid:configChanges="orientation|screenSize"
Pacerier
9
android:configChanges="orientation|screenSize"funktioniert bei mir. Danke @Pacerier
Don Larynx
1
Bitte aktualisieren Sie Ihren Antwortfall Nr. 3 mit dem android:configChanges="orientation|screenSize"Wert für API> = 13, da viele Leute Ihre Antwort als Hauptantwort ansehen!
Radistao
215

Xions Antwort war knapp, aber # 3 ( android:configChanes="orientation") funktioniert nur, wenn die Anwendung eine API-Stufe von 12 oder niedriger hat.

In API-Version 13 oder höher ändert sich die Bildschirmgröße, wenn sich die Ausrichtung ändert. Dadurch wird die Aktivität weiterhin zerstört und gestartet, wenn sich die Ausrichtung ändert.

Fügen Sie einfach das Attribut "screenSize" hinzu, wie ich es unten getan habe:

<activity
    android:name=".YourActivityName"
    android:configChanges="orientation|screenSize">
</activity>

Wenn Sie nun die Ausrichtung ändern (und die Bildschirmgröße ändert), behält die Aktivität ihren Status bei und onConfigurationChanged()wird aufgerufen. Dadurch bleibt alles auf dem Bildschirm (z. B. Webseite in einer Webansicht) erhalten, wenn sich die Ausrichtung ändert.

Das haben Sie auf dieser Website gelernt: http://developer.android.com/guide/topics/manifest/activity-element.html

Dies ist anscheinend auch eine schlechte Praxis. Lesen Sie daher den folgenden Link zum Umgang mit Laufzeitänderungen:

http://developer.android.com/guide/topics/resources/runtime-changes.html

corbin
quelle
2
Danke ... seine Arbeit nach dem Hinzufügen von "screenSize" mit "Orientierung"
Pratik Butani
Funktioniert in Samsung Galaxy Nexus Android 4.2.1! android:configChanges="orientation|screenSize"
Vincent Ducastel
Tolle. Ich habe so viele Stunden lang Code durchgearbeitet, um ein Problem zu lösen, das ich beim erneuten Laden von Aktivitäten und einem Video von Anfang an hatte. Und hier war die Lösung! ++++ 1
Mathias Asberg
6
Schlechte Praxis? Pfft, echte Menschen haben Fristen und wenn es funktioniert, funktioniert es;)
Kacy
Wenn dies eine schlechte Praxis ist, warum hat es dann so viele positive Stimmen bekommen?
Sharp Edge
26

Sie müssen nur zum AndroidManifest.xmlund innerhalb oder in Ihren Aktivitätsetiketten gehen, Sie müssen diese Codezeile eingeben, wie jemand dort oben sagte:

android:configChanges="orientation|screenSize"

Sie haben also ungefähr Folgendes:

<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>

Hoffe, es funktioniert!

Josue Rocha
quelle
Es wird mein Layout-Land-Layout nicht geladen. :( hat bei mir nicht funktioniert
piyush poriya
16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

Einfach hinzufügen android:configChanges="orientation|screenSize" Registerkarte Aktivität der Manifestdatei hinzu.

Die Aktivität wird also nicht neu gestartet, wenn sich die Ausrichtung ändert.

Aiyaz Parmar
quelle
Es funktioniert. Aber wenn ich für jede Ausrichtung ein separates Layout verwende layout.xml und layout-land.xml. Es wendet das Querformat für beide Orientierungen an. Wenn ich nur "Orientierung" verwende, gibt es das, was ich erwarte, aber das Nachladen. Könnten Sie dabei helfen?
Karthikeyan Ve
1
@KarthikeyanVe Das ist das Problem, wenn Sie versuchen zu betrügen. Sie müssen Ihre Aktivität neu starten, um das Layout zu ändern. Gehen Sie voran und verwenden Sie einfach die reale Lösung, die onSaveInstanceState()und verwendet onCreate().
Marc Plano-Lesay
@ MarcPlano-Lesay und wie soll ich das machen?
Ahsan
@ Weaboo die eigentliche Lösung ist in der Frage verlinkt: developer.android.com/guide/topics/resources/…
Marc Plano-Lesay
@ MarcPlano-Lesay Ich habe ein separates Layout für den Hoch- und Querformat. Wenn ich meine App im Quer- oder Hochformat öffne, funktioniert dies einwandfrei. Wenn ich jedoch versuche, die Ausrichtung zur Laufzeit zu ändern, wird meine App geschlossen, wenn ich mich jedoch bei meiner App anmelde Navigieren Sie dann zu MainActivity und versuchen Sie, die Ausrichtung zu ändern. Dadurch wird diese Aktivität neu geladen und funktioniert einwandfrei. Nun ist die Frage warum? Gibt es einen logischen Fehler in meinem Code? Idk, aber ich habe mehrmals versucht, die App zu debuggen, und ich kann nichts finden. Außerdem möchte ich meine Aktivität nicht neu starten. Warum können wir das jeweilige Layout nicht einfach anpassen, wenn sich die Konfiguration ändert?
Ahsan
10

Ich habe die Erfahrung gemacht, dass es eigentlich besser ist, nur mit den Orientierungsänderungen richtig umzugehen, als zu versuchen, ein nicht standardmäßiges Verhalten zu erkennen.

Sie sollten das aktuell angezeigte Bild speichern onSaveInstanceState()und ordnungsgemäß wiederherstellen, wenn Ihre Anwendung onCreate()erneut ausgeführt wird.

dmon
quelle
# 3 ist eine absolut gültige Lösung. Es ist das genaue Werkzeug, um dieses genaue Problem zu lösen. Warum sagst du, dass es Schuhmorgen ist?
Pacerier
1
@ Pacerier Lesen Sie einfach die Dokumente. "Hinweis: Die Verwendung android:configChangessollte vermieden und nur als letzter Ausweg verwendet werden. Weitere Informationen zur ordnungsgemäßen Behandlung eines Neustarts aufgrund einer Konfigurationsänderung finden Sie unter Behandeln von Laufzeitänderungen ."
Marc Plano-Lesay
Könnten Sie ein Beispiel zum Speichern und Wiederherstellen veröffentlichen?
Pollaris
6

Diese Lösung ist bei weitem die am besten funktionierende. Fügen Sie in Ihrer Manifestdatei hinzu

<activity
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:name="your activity name"
    android:label="@string/app_name" 
    android:screenOrientation="landscape">
  </activity

Fügen Sie in Ihrer Aktivitätsklasse den folgenden Code hinzu

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //your code
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
  //your code

    }
}
Ein Raj
quelle
4

Fügen Sie android:configChanges="keyboardHidden|orientation|screenSize"für alle App-Aktivitäten Tags im Manifest hinzu.

Oubaida AlQuraan
quelle
3

Fügen Sie dies einfach zu Ihrem hinzu AndroidManifest.xml

<activity android:screenOrientation="landscape">

Ich meine, es gibt ein Aktivitäts-Tag. Fügen Sie dies als weiteren Parameter hinzu. Wenn Sie eine Hochformatausrichtung benötigen, ändern Sie die Querformatstruktur in Hochformat. Hoffe das hilft.

Egor
quelle
Ich möchte nicht die Möglichkeit nehmen, den Bildschirm zu drehen. Ich möchte nur nicht, dass meine App neu geladen wird ... wie ich bereits erwähnt habe.
Jimmy D
ps ... das funktioniert sowieso nicht. Es zwingt die App lediglich dazu, in einer bestimmten Ausrichtung anzuzeigen. Durch Drehen des Bildschirms wird die Aktivität immer noch neu geladen
Jimmy D,
3

Fügen Sie in jeder Datei zu jeder Aktivität diese hinzu. Das wird helfen

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"
Jevgenij Kononov
quelle
screenLayout funktionierte für mich und verhinderte eine Aktualisierung beim Ändern der Größe der App für Splitscreen auf Android
Terren
2

Alle oben genannten Antworten funktionieren bei mir nicht. Also habe ich behoben, indem ich das labelmit screenOrientationwie unten erwähne . Jetzt ist alles in Ordnung

<activity android:name=".activity.VideoWebViewActivity"
        android:label="@string/app_name"
        android:configChanges="orientation|screenSize"/>
Bahu
quelle
1

Speichern Sie die Bilddetails in Ihrem onPause()oder onStop()und verwenden Sie sie in onCreate(Bundle savedInstanceState), um das Bild wiederherzustellen.

BEARBEITEN:

Weitere Informationen zum eigentlichen Prozess finden Sie hier http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle, da es sich in Honeycomb von früheren Android-Versionen unterscheidet.

techiServices
quelle
Eigentlich sollten Sie es in der onSaveInstanceState () -Methode tun
Willi Mentzel
1

benutz einfach : android:configChanges="keyboardHidden|orientation"

Masoud Banimahd
quelle
1

Wie Pacerier erwähnte,

android:configChanges="orientation|screenSize"

Don Larynx
quelle
-1

Ich weiß nicht, ob die beste Lösung ist, aber ich beschreibe sie hier:

Zuallererst benötigen Sie ein Zertifikat mit Ihrer Klasse. Die Anwendung Ihrer App ist in Ihrem Manifest davon:

<application
    android:name=".App"
    ...

Zweitens hat mir in meiner Klassen-App Folgendes gefallen:

public class App extends Application {
    public static boolean isOrientationChanged = false;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(@NotNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ||
                newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            isOrientationChanged = true;
        }
    }

}

Drittens müssen Sie ein Flag auf Orientierungsänderung setzen. In meinem Fall setze ich es immer, wenn die vorherige Aktivität in der App-Navigation aufgerufen wird. Rufen Sie also nur einmal auf, wenn die spätere Aktivität erstellt wird.

isOrientationChanged = false;

Jedes Mal, wenn ich die Ausrichtung meines Bildschirms in diesem Kontext ändere, setze ich sie jedes Mal, wenn ich diese Einstellung ändere. Sie prüft, ob sich die Ausrichtung ändert. Wenn ja, wird sie anhand des Werts dieses Flags überprüft.

Grundsätzlich musste ich es verwenden, wenn ich eine asynchrone Nachrüstanforderung stellte, die er jeden Moment aufrief, der die Ausrichtung änderte und die Anwendung ständig zum Absturz brachte:

if (!isOrientationChanged) {
    presenter.retrieveAddress(this, idClient, TYPE_ADDRESS);
}

Ich weiß nicht, ob es die eleganteste und schönste Lösung ist, aber zumindest hier ist es funktional :)

michel566
quelle
-2

Fügen Sie diesen Code nach der onCreateMethode in Ihrer Aktivität hinzu, die die enthältWebView

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}
Amir Aslam
quelle
1
Wie würde das funktionieren? Sagen Sie nicht einfach etwas explizit zur Laufzeit, was würde sonst standardmäßig getan werden?
Danielson