Posts mit dem Label Activity werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Activity werden angezeigt. Alle Posts anzeigen

21. April 2013

Android: Automatische Drehung einer Activity verhindern

Um in einer Android-App den Orientierungswechsel einer Activity zu unterbinden, wenn das Gerät gedreht wird, gibt es die Möglichkeit, eine bestimmte Orientierung fest vorzuschreiben. Dies kann entweder über ein entsprechendes Attribute in der AndroidManifest.xml oder im Code der Activity geschehen.

Um die Orientierung in der AndroidManifest.xml fest vorzuschreiben, genügt es, die Definition der jeweiligen Activity folgendermaßen zu erweitern:
 <activity  
   android:name=".Activity"  
   android:label="@string/app_name"  
   android:screenOrientation="portrait" >  
   <intent-filter>  
     <action android:name="android.intent.action.MAIN" />  
     <category android:name="android.intent.category.LAUNCHER" />  
   </intent-filter>  
 </activity>  

Durch setzen des Attributs android:screenOrientation auf den Wert "portrait" wird die Orientierung der Activity auf den Portraitmodus, also das Hochkantformat, festgelegt. Soll stattdessen der Landscape-Modus verwendet werden, muss der Wert auf "landscape" gesetzt werden.

Um die Orientierung stattdessen im Code zu setzen muss in der jeweiligen Activity folgender Befehl aufgerufen werden:
 setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);  

Auch bei dieser Variante muss der Wert ORIENTATION_PORTRAIT auf ORIENTATION_LANDSCAPE geändert werden, falls der Landscape-Modus gesetzt werden soll. Um die Festlegung der Orientierung später wieder aufzuheben, kann der Wert auf ORIENTATION_UNDEFINED gesetzt werden.

Statt die Orientierung bereits im Vorraus fest zu setzen, ist es manchmal gewollt, die Activity der aktuellen Ausrichtung des Geräts nach zu starten, anschließend aber keinen Orientierungswechsel mehr zu erlauben. Ein solches Verhalten ist über folgenden Code realisierbar:
 @Override  
 public final void onCreate(final Bundle savedInstanceState) {  
   super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_layout);  
   if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {  
     setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);  
   } else {  
     setRequestedOrientation(Configuration.ORIENTATION_LANDSCAPE);  
   }  
 }  

Hierbei wird nach dem Starten der Activity die aktuelle Orientierung über den Befehl getResources().getConfiguration().orientation ausgelesen und abhängig von ihrem Wert anschließend über den bereits oben erwähnten Befehl festgelegt.

Android: ActionBar verbergen

Um in einer Android-App die ActionBar einer bestimmten Activity zu verbergen, bzw. die Activity als Fullscreen darzustellen, genügt das Hinzufügen eines entsprechenden Attributs in der AndroidManifest.xml. Die Definition der jeweiligen Activity muss dabei, wie in folgendem Beispiel verdeutlicht, um das Attribut android:theme erweitert werden:
 <activity  
   android:name=".Activity"  
   android:label="@string/app_name"  
   android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" >  
   <intent-filter>  
     <action android:name="android.intent.action.MAIN" />  
     <category android:name="android.intent.category.LAUNCHER" />  
   </intent-filter>  
 </activity>  
In diesem Beispiel wird die Activity mit einem hellen Hintergrund dargestellt, so wie es bei dem Theme "Holo Light" üblich ist. Wenn die App stattdessen ein dunkles Theme verwendet, muss statt Theme.Light.NoTitleBar.Fullscreen der Wert Theme.Black.NoTitleBar.Fullscreen verwendet werden um einen dunklen Hintergrund darzustellen.

Bei dieser Vorgehensweise ist zu beachten, dass die Activity-Methode getActionBar() eine Null-Referenz zurück liefert, da keine ActionBar erzeugt wird.

9. Februar 2013

Android: Die Activity-Methoden onSaveInstanceState und onRestoreInstanceState

Standardmäßig verlieren die Activities einer Android-App temporäre Werte, wie Eingaben in Textfelder, die Auswahl von Checkboxen oder ähnliches, wenn sie neu erzeugt werden. Dies kommt beispielsweise vor, wenn vom Portrait- in den Landscape-Modus gewechselt wird oder umgekehrt und ist in so einem Fall oft unerwünscht. Deshalb bietet die Android-API die beiden Methoden onSaveInstanceState(Bundle outState): void und onRestoreInstanceState(Bundle savedInstanceState): void an, die es ermöglichen, zu erhaltene Zustände zwischenzuspeichern und anschließend wiederherzustellen. Die beiden Methoden werden dabei, dem Activity-Lifecycle entsprechend automatisch aufgerufen. Das folgende kurze Beispiel soll die Verwendung der beiden Methoden demonstrieren.

Der Activity-Lifecycle (Bildquelle: www.developer.android.com, Klicken zum Vergrößern)

Das folgende XML Layout File definiert die Oberfläche einer Activity, die ein Textfeld enthält. Ist dort ein Text eingetragen, geht dieser verloren, wenn vom Portrait- in den Landscape-Modus gewechselt wird, oder umgekehrt. Dieser unerwünschte Effekt soll im Folgenden behoben werden.

 <?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" >   
     
   <EditText   
    android:id="@+id/edit"   
    android:layout_width="fill_parent"   
    android:layout_height="wrap_content" >   
     
  </LinearLayout>   
Der Code der dazugehörigen Activity, inklusive der beiden oben genannten Methoden zum Speichern und Wiederherstellen des eingegebenen Textes, sieht dabei folgendermaßen aus:
 public class ExampleActivity extends Activity {  
   
   EditText edit;  
   
   @Override  
   public void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.main);  
      
     edit = (EditText)findViewById(R.id.edit);  
   }  
   
   @Override  
   public void onSaveInstanceState(Bundle outState) {  
    super.onSaveInstanceState(outState);  
    outState.putString("text", (String) text.getText());  
   }  
   
   @Override  
   public void onRestoreInstanceState(Bundle savedInstanceState) {  
    super.onRestoreInstanceState(savedInstanceState);  
    text.setText(savedInstanceState.getString("text"));  
   }  
    
 }  
Beim Erzeugen der Activity durch die onCreate-Methode wird das, im XML-File definierte, Textfeld zunächst anhand seiner ID referenziert. Bevor die Activity, beispielsweise durch ein Rotieren des Bildschirms, zerstört wird, wird automatisch die onSaveInstanceState-Methode aufgerufen, in der alle zu sichernden Werte zusammen mit einem String als Key in einem Bundle abgelegt werden können, das als Parameter übergeben wird. Das selbe Bundle wird dann an die onRestoreInstanceState-Methode übergeben, sobald die Activity neu erzeugt wurde. Die gespeicherten Werte können dann über den zuvor angegebenen Schlüssel aus dem Bundle gelesen und zur Wiederherstellung des vorherigen Zustandes verwendet werden.

Nachtrag vom 20. Februar 2013: Unter diesem Post ist von nun an die analoge Vorgehensweise zur Zwischenspeicherung von Zuständen in Fragments beschrieben.