Verarbeiten der DrehungHandling Rotation

In diesem Thema wird beschrieben, wie Änderungen an der Geräte Orientierung in xamarin. Android behandelt werden. Es wird erläutert, wie Sie mit dem Android-Ressourcensystem zum automatischen Laden von Ressourcen für eine bestimmte Geräte Orientierung und zum programmgesteuerten behandeln von Richtungsänderungen arbeiten.This topic describes how to handle device orientation changes in Xamarin.Android. It covers how to work with the Android resource system to automatically load resources for a particular device orientation as well as how to programmatically handle orientation changes.

ÜbersichtOverview

Da mobile Geräte problemlos gedreht werden, ist die integrierte Rotation ein Standard Feature in mobilen Betriebssystemen.Because mobile devices are easily rotated, built-in rotation is a standard feature in mobile OSes. Android stellt ein ausgereiftes Framework für den Umgang mit der Drehung innerhalb von Anwendungen bereit, unabhängig davon, ob die Benutzeroberfläche deklarativ in XML oder Programm gesteuert in Code erstellt wird.Android provides a sophisticated framework for dealing with rotation within applications, whether the user interface is created declaratively in XML or programmatically in code. Bei der automatischen Verarbeitung von deklarativen Layoutänderungen auf einem gedrehten Gerät kann eine Anwendung von der engen Integration in das Android-Ressourcensystem profitieren.When automatically handling declarative layout changes on a rotated device, an application can benefit from the tight integration with the Android resource system. Für das programmgesteuerte Layout müssen Änderungen manuell behandelt werden.For programmatic layout, changes must be handled manually. Dies ermöglicht eine präzisere Steuerung zur Laufzeit, aber auf Kosten der Arbeit für den Entwickler.This allows finer control at runtime, but at the expense of more work for the developer. Eine Anwendung kann sich auch entscheiden, den Neustart der Aktivität zu beenden und die Richtungsänderungen manuell zu steuern.An application can also choose to opt out of the Activity restart and take manual control of orientation changes.

In diesem Leitfaden werden die folgenden Themen zur Orientierung erläutert:This guide examines the following orientation topics:

  • Deklarative layoutrotation – die Verwendung des Android-ressourcensystems zum Erstellen von nach Orientierung unterstützenden Anwendungen, einschließlich des Ladens von Layouts und drawables für bestimmte Ausrichtungen.Declarative Layout Rotation – How to use the Android resource system to build orientation-aware applications, including how to load both layouts and drawables for particular orientations.

  • Die programmgesteuerte layoutrotation –, wie Steuerelemente Programm gesteuert hinzugefügt werden, und wie die Ausrichtung von Änderungen manuell behandelt werden.Programmatic Layout Rotation – How to add controls programmatically as well as how to handle orientation changes manually.

Deklarative Behandlung der Drehung mit LayoutsHandling Rotation Declaratively with Layouts

Wenn Sie Dateien in Ordner einschließen, die den Benennungs Konventionen folgen, lädt Android automatisch die entsprechenden Dateien, wenn sich die Ausrichtung ändert.By including files in folders that follow naming conventions, Android automatically loads the appropriate files when the orientation changes. Dies umfasst die Unterstützung für:This includes support for:

  • Layoutressourcen – festlegen, welche Layoutdateien für jede Ausrichtung aufgeblasen werden.Layout Resources – Specifying which layout files are inflated for each orientation.

  • Drawable-Ressourcen – die angeben, welche drawables für jede Ausrichtung geladen werden.Drawable Resources – Specifying which drawables are loaded for each orientation.

LayoutressourcenLayout Resources

Standardmäßig werden im Ordner " Resources/Layout " enthaltene Android XML (axml)-Dateien zum Rendern von Ansichten für eine Aktivität verwendet.By default, Android XML (AXML) files included in the Resources/layout folder are used for rendering views for an Activity. Die Ressourcen dieses Ordners werden sowohl für hoch-als auch für Querformat verwendet, wenn keine zusätzlichen layoutressourcen speziell für das Querformat bereitgestellt werden.This folder's resources are used for both portrait and landscape orientation if no additional layout resources are provided specifically for landscape. Beachten Sie die Projektstruktur, die von der Standard Projektvorlage erstellt wurde:Consider the project structure created by the default project template:

standardmäßige Projektvorlagen StrukturDefault project template structure

Dieses Projekt erstellt eine einzelne Datei " Main. axml " im Ordner " Resources/Layout ".This project creates a single Main.axml file in the Resources/layout folder. Wenn die OnCreate-Methode der Aktivität aufgerufen wird, vergrößert Sie die in Main. axml definierte Sicht, die eine Schaltfläche deklariert, wie im folgenden XML-Code dargestellt:When the Activity's OnCreate method is called, it inflates the view defined in Main.axml, which declares a button as shown in the XML below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
<Button  
  android:id="@+id/myButton"
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:text="@string/hello"/>
</LinearLayout>

Wenn das Gerät in Querformat gedreht wird, wird die OnCreate-Methode der Aktivität erneut aufgerufen, und die gleiche Datei " Main. axml " wird aufgeblasen, wie im folgenden Screenshot zu sehen:If the device is rotated to landscape orientation, the Activity's OnCreate method is called again and the same Main.axml file is inflated, as shown in the screenshot below:

gleichen Bildschirm, aber in QuerformatSame screen but in landscape orientation

Orientierungs spezifische LayoutsOrientation-Specific Layouts

Zusätzlich zum layoutordner (der standardmäßig Hochformat ist und auch explizit als layoutport bezeichnet werden kann, indem ein Ordner mit dem Namen "layout-land") verwendet wird, kann eine Anwendung die Ansichten definieren, die im Querformat ohne Codeänderungen erforderlich sind.In addition to the layout folder (which defaults to portrait and can also be explicitly named layout-port by including a folder named layout-land), an application can define the views it needs when in landscape without any code changes.

Angenommen, die Datei Main. axml enthält den folgenden XML-Code:Suppose the Main.axml file contained the following XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:text="This is portrait"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" />
</RelativeLayout>

Wenn ein Ordner mit dem Namen Layout-Land, der eine zusätzliche Datei " Main. axml " enthält, dem Projekt hinzugefügt wird, führt die Vergrößerung des Layouts im Querformat jetzt dazu, dass Android das neu hinzugefügte " Main. axml " lädt.If a folder named layout-land that contains an additional Main.axml file is added to the project, inflating the layout when in landscape will now result in Android loading the newly added Main.axml. Sehen Sie sich die quer Version der Datei " Main. axml " an, die den folgenden Code enthält (aus Gründen der Einfachheit ist dieser XML-Code der standardmäßigen Hochformat Version des Codes ähnlich, verwendet aber eine andere Zeichenfolge in der TextView):Consider the landscape version of the Main.axml file that contains the following code (for simplicity, this XML is similar to the default portrait version of the code, but uses a different string in the TextView):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:text="This is landscape"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" />
</RelativeLayout>

Wenn Sie diesen Code ausführen und das Gerät vom Hochformat in das Querformat drehen, wird das neue XML-laden veranschaulicht, wie unten dargestellt:Running this code and rotating the device from portrait to landscape demonstrates the new XML loading, as shown below:

hoch-und Querformat Screenshots Drucken des Hochformat ModusPortrait and landscape screenshots printing the portrait mode

Drawable-RessourcenDrawable Resources

Während der Rotation behandelt Android drawable-Ressourcen ähnlich wie layoutressourcen.During rotation, Android treats drawable resources similarly to layout resources. In diesem Fall ruft das System die drawables aus den Ordnern Resources/drawable bzw. Resources/drawable-Land ab.In this case, the system gets the drawables from the Resources/drawable and Resources/drawable-land folders, respectively.

Nehmen Sie beispielsweise an, das Projekt enthält ein Image mit dem Namen "Monkey. png" im Ordner " Resources/drawable ", in dem auf die drawable aus einer ImageView in XML wie folgt verwiesen wird:For example, say the project includes an image named Monkey.png in the Resources/drawable folder, where the drawable is referenced from an ImageView in XML like this:

<ImageView
  android:layout_height="wrap_content"
  android:layout_width="wrap_content"
  android:src="@drawable/monkey"
  android:layout_centerVertical="true"
  android:layout_centerHorizontal="true" />

Nehmen wir weiter an, dass eine andere Version von " Monkey. png " unter " Resources/drawable-Land" enthalten ist.Let's further assume that a different version of Monkey.png is included under Resources/drawable-land. Ebenso wie bei den Layoutdateien ändert sich das drawable-Element für die angegebene Ausrichtung, wie unten dargestellt:Just like with the layout files, when the device is rotated, the drawable changes for the given orientation, as shown below:

andere Version von "Monkey. png" im hoch-und QuerformatDifferent version of Monkey.png shown in portrait and landscape modes

Programm gesteuertes behandeln der RotationHandling Rotation Programmatically

Manchmal werden Layouts im Code definiert.Sometimes we define layouts in code. Dies kann aus verschiedenen Gründen geschehen, wie z. b. technische Einschränkungen, Entwickler Präferenz usw. Wenn Sie Steuerelemente Programm gesteuert hinzufügen, muss eine Anwendung die Geräte Ausrichtung manuell berücksichtigen. diese wird automatisch bei der Verwendung von XML-Ressourcen behandelt.This can happen for a variety of reasons, including technical limitations, developer preference, etc. When we add controls programmatically, an application must manually account for device orientation, which is handled automatically when we use XML resources.

Hinzufügen von Steuerelementen im CodeAdding Controls in Code

Zum programmgesteuerten Hinzufügen von Steuerelementen muss eine Anwendung die folgenden Schritte ausführen:To add controls programmatically, an application needs to perform the following steps:

  • Erstellen Sie ein Layout.Create a layout.
  • Legen Sie Layoutparameter fest.Set layout parameters.
  • Erstellen von SteuerelementenCreate controls.
  • Festlegen von Steuerelement Layout-ParameternSet control layout parameters.
  • Fügen Sie dem Layout Steuerelemente hinzu.Add controls to the layout.
  • Legen Sie das Layout als Inhaltsansicht fest.Set the layout as the content view.

Angenommen, eine Benutzeroberfläche besteht aus einem einzelnen TextView Steuerelement, das einer RelativeLayouthinzugefügt wurde, wie im folgenden Code gezeigt.For example, consider a user interface consisting of a single TextView control added to a RelativeLayout, as shown in the following code.

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);
                        
  // create a layout
  var rl = new RelativeLayout (this);

  // set layout parameters
  var layoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.FillParent);
  rl.LayoutParameters = layoutParams;
        
  // create TextView control
  var tv = new TextView (this);

  // set TextView's LayoutParameters
  tv.LayoutParameters = layoutParams;
  tv.Text = "Programmatic layout";

  // add TextView to the layout
  rl.AddView (tv);
        
  // set the layout as the content view
  SetContentView (rl);
}

Mit diesem Code wird eine Instanz einer RelativeLayout-Klasse erstellt und deren LayoutParameters-Eigenschaft festgelegt.This code creates an instance of a RelativeLayout class and sets its LayoutParameters property. Die LayoutParams-Klasse stellt die Art und Weise dar, wie Steuerelemente auf wiederverwendbare Weise positioniert werden.The LayoutParams class is Android's way of encapsulating how controls are positioned in a reusable way. Nachdem eine Instanz eines Layouts erstellt wurde, können Steuerelemente erstellt und hinzugefügt werden.Once an instance of a layout is created, controls can be created and added to it. Steuerelemente haben auch LayoutParameters, z. b. die TextView in diesem Beispiel.Controls also have LayoutParameters, such as the TextView in this example. Nachdem die TextView erstellt wurde, wird Sie der RelativeLayout hinzugefügt und die RelativeLayout als Inhaltsansicht festgelegt, sodass die Anwendung die TextView wie gezeigt anzeigt:After the TextView is created, adding it to the RelativeLayout and setting the RelativeLayout as the content view results in the application displaying the TextView as shown:

im hoch-und Querformat angezeigte Schaltfläche "Inkrement Counter"Increment counter button shown in both portrait and landscape modes

Erkennen der Ausrichtung im CodeDetecting Orientation in Code

Wenn eine Anwendung versucht, eine andere Benutzeroberfläche für jede Ausrichtung zu laden, wenn OnCreate aufgerufen wird (Dies geschieht bei jedem Drehen eines Geräts), muss die Ausrichtung erkannt und der gewünschte Benutzeroberflächen Code geladen werden.If an application tries to load a different user interface for each orientation when OnCreate is called (this will happen each time a device is rotated), it must detect the orientation, and then load the desired user interface code. Android verfügt über eine Klasse mit dem Namen WindowManager, die verwendet werden kann, um die aktuelle Geräte Drehung über die WindowManager.DefaultDisplay.Rotation-Eigenschaft zu bestimmen, wie unten dargestellt:Android has a class called the WindowManager, which can be used to determine the current device rotation via the WindowManager.DefaultDisplay.Rotation property, as shown below:

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);
                        
  // create a layout
  var rl = new RelativeLayout (this);

  // set layout parameters
  var layoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.FillParent);
  rl.LayoutParameters = layoutParams;
                        
  // get the initial orientation
  var surfaceOrientation = WindowManager.DefaultDisplay.Rotation;
  // create layout based upon orientation
  RelativeLayout.LayoutParams tvLayoutParams;
                
  if (surfaceOrientation == SurfaceOrientation.Rotation0 || surfaceOrientation == SurfaceOrientation.Rotation180) {
    tvLayoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
  } else {
    tvLayoutParams = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
    tvLayoutParams.LeftMargin = 100;
    tvLayoutParams.TopMargin = 100;
  }
                        
  // create TextView control
  var tv = new TextView (this);
  tv.LayoutParameters = tvLayoutParams;
  tv.Text = "Programmatic layout";
        
  // add TextView to the layout
  rl.AddView (tv);
        
  // set the layout as the content view
  SetContentView (rl);
}

Dieser Code legt fest, dass die TextView 100 Pixel von oben links auf dem Bildschirm positioniert werden, wobei beim Drehen auf das neue Layout automatisch eine Animation durchlaufen wird, wie hier gezeigt:This code sets the TextView to be positioned 100 pixels from the top left of the screen, automatically animating to the new layout, when rotated to landscape, as shown here:

derAnsichts Zustand wird im hoch-und Querformat beibehalten.View state is preserved across portrait and landscape modes

Verhindern von Neustart der AktivitätPreventing Activity Restart

Zusätzlich zur Verarbeitung der gesamten OnCreatekann eine Anwendung auch verhindern, dass eine Aktivität neu gestartet wird, wenn sich die Ausrichtung ändert, indem Sie ConfigurationChanges im ActivityAttribute wie folgt festlegt:In addition to handling everything in OnCreate, an application can also prevent an Activity from being restarted when the orientation changes by setting ConfigurationChanges in the ActivityAttribute as follows:

[Activity (Label = "CodeLayoutActivity", ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]

Wenn das Gerät nun gedreht wird, wird die Aktivität nicht neu gestartet.Now when the device is rotated, the Activity is not restarted. Um die Orientierungs Änderung in diesem Fall manuell zu verarbeiten, kann eine Aktivität die OnConfigurationChanged Methode überschreiben und die Ausrichtung des Configuration Objekts bestimmen, das wie in der neuen Implementierung der folgenden Aktivität weitergegeben wird:In order to manually handle the orientation change in this case, an Activity can override the OnConfigurationChanged method and determine the orientation from the Configuration object that is passed in, as in the new implementation of the Activity below:

[Activity (Label = "CodeLayoutActivity", ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
public class CodeLayoutActivity : Activity
{
  TextView _tv;
  RelativeLayout.LayoutParams _layoutParamsPortrait;
  RelativeLayout.LayoutParams _layoutParamsLandscape;
                
  protected override void OnCreate (Bundle bundle)
  {
    // create a layout
    // set layout parameters
    // get the initial orientation

    // create portrait and landscape layout for the TextView
    _layoutParamsPortrait = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
                
    _layoutParamsLandscape = new RelativeLayout.LayoutParams (ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
    _layoutParamsLandscape.LeftMargin = 100;
    _layoutParamsLandscape.TopMargin = 100;
                        
    _tv = new TextView (this);
                        
    if (surfaceOrientation == SurfaceOrientation.Rotation0 || surfaceOrientation == SurfaceOrientation.Rotation180) {
      _tv.LayoutParameters = _layoutParamsPortrait;
    } else {
      _tv.LayoutParameters = _layoutParamsLandscape;
    }
                        
    _tv.Text = "Programmatic layout";
    rl.AddView (_tv);
    SetContentView (rl);
  }
                
  public override void OnConfigurationChanged (Android.Content.Res.Configuration newConfig)
  {
    base.OnConfigurationChanged (newConfig);
                        
    if (newConfig.Orientation == Android.Content.Res.Orientation.Portrait) {
      _tv.LayoutParameters = _layoutParamsPortrait;
      _tv.Text = "Changed to portrait";
    } else if (newConfig.Orientation == Android.Content.Res.Orientation.Landscape) {
      _tv.LayoutParameters = _layoutParamsLandscape;
      _tv.Text = "Changed to landscape";
    }
  }
}

Hier werden die TextView's Layoutparameter sowohl für Landscape als auch für Hochformat initialisiert.Here the TextView's layout parameters are initialized for both landscape and portrait. Klassen Variablen enthalten die Parameter zusammen mit dem TextView selbst, da die Aktivität bei einer Änderung der Ausrichtung nicht neu erstellt wird.Class variables hold the parameters, along with the TextView itself, since the Activity will not be re-created when orientation changes. Der Code verwendet weiterhin den surfaceOrientartion in OnCreate, um das anfängliche Layout für die TextViewfestzulegen.The code still uses the surfaceOrientartion in OnCreate to set the initial layout for the TextView. Danach verarbeitet OnConfigurationChanged alle nachfolgenden Layoutänderungen.After that, OnConfigurationChanged handles all subsequent layout changes.

Wenn Sie die Anwendung ausführen, lädt Android die Änderungen an der Benutzeroberfläche, während die Geräte Drehung erfolgt, und startet die Aktivität nicht neu.When we run the application, Android loads the user interface changes as device rotation occurs, and does not restart the Activity.

Verhindern des Neustarts von Aktivitäten für deklarative LayoutsPreventing Activity Restart for Declarative Layouts

Aktivitäts Neustarts, die durch die Geräte Drehung verursacht werden, können auch verhindert werden, wenn das Layout in XML definiert wird.Activity restarts caused by device rotation can also be prevented if we define the layout in XML. Beispielsweise können wir diesen Ansatz verwenden, wenn wir einen Aktivitäts Neustart verhindern möchten (aus Leistungsgründen), und wir müssen keine neuen Ressourcen für verschiedene Ausrichtungen laden.For example, we can use this approach if we want to prevent an Activity restart (for performance reasons, perhaps) and we don't need to load new resources for different orientations.

Zu diesem Zweck befolgen wir das gleiche Verfahren wie bei einem programmatischen Layout.To do this, we follow the same procedure that we use with a programmatic layout. Legen Sie einfach ConfigurationChanges in der ActivityAttributefest, wie dies in der CodeLayoutActivity zuvor geschehen ist.Simply set ConfigurationChanges in the ActivityAttribute, as we did in the CodeLayoutActivity earlier. Sämtlicher Code, der für die Ausrichtung der Ausrichtung ausgeführt werden muss, kann in der OnConfigurationChanged-Methode wieder implementiert werden.Any code that does need to run for the orientation change can again be implemented in the OnConfigurationChanged method.

Beibehalten des Zustands bei der Ausrichtung von ÄnderungenMaintaining State During Orientation Changes

Unabhängig davon, ob die Rotation deklarativ oder Programm gesteuert verarbeitet wird, sollten alle Android-Anwendungen dieselben Verfahren zum Verwalten des Zustands implementieren, wenn sich die Geräte Ausrichtung ändert.Whether handling rotation declaratively or programmatically, all Android applications should implement the same techniques for managing state when device orientation changes. Das Verwalten des Zustands ist wichtig, da das System eine laufende Aktivität neu startet, wenn ein Android-Gerät gedreht wird.Managing state is important because the system restarts a running Activity when an Android device is rotated. Dies erleichtert Android das Laden alternativer Ressourcen, z. b. Layouts und drawables, die speziell für eine bestimmte Ausrichtung entworfen wurden.Android does this to make it easy to load alternate resources, such as layouts and drawables that are designed specifically for a particular orientation. Beim Neustart verliert die Aktivität jeden vorübergehenden Zustand, der möglicherweise in lokalen Klassen Variablen gespeichert wurde.When it restarts, the Activity loses any transient state it may have stored in local class variables. Wenn eine Aktivität Zustands abhängig ist, muss Sie daher ihren Zustand auf Anwendungsebene beibehalten.Therefore, if an Activity is state reliant, it must persist its state at the application level. Eine Anwendung muss das Speichern und Wiederherstellen von Anwendungs Zuständen durchführen, die über Richtungsänderungen hinweg beibehalten werden sollen.An application needs to handle saving and restoring any application state that it wants to preserve across orientation changes.

Weitere Informationen zum Beibehalten des Zustands in Android finden Sie im Handbuch zum Aktivitäts Lebenszyklus .For more information on persisting state in Android, refer to the Activity Lifecycle guide.

ZusammenfassungSummary

In diesem Artikel wurde beschrieben, wie die integrierten Funktionen von Android für die Rotation verwendet werden.This article covered how to use Android's built-in capabilities to work with rotation. Zunächst wurde erläutert, wie das Android-Ressourcensystem zum Erstellen von Richtungs fähigen Anwendungen verwendet wird.First, it explained how to use the Android resource system to create orientation aware applications. Anschließend haben Sie erfahren, wie Sie Steuerelemente im Code hinzufügen und wie Sie die Ausrichtung von Änderungen manuell behandeln können.Then it presented how to add controls in code as well as how to handle orientation changes manually.