Ich möchte, dass Tablets im Hoch- und Querformat (sw600dp oder höher) angezeigt werden können, Telefone jedoch nur im Hochformat. Ich kann keine Möglichkeit finden, eine Orientierung bedingt zu wählen. Irgendwelche Vorschläge?
Ich möchte, dass Tablets im Hoch- und Querformat (sw600dp oder höher) angezeigt werden können, Telefone jedoch nur im Hochformat. Ich kann keine Möglichkeit finden, eine Orientierung bedingt zu wählen. Irgendwelche Vorschläge?
Antworten:
Hier ist eine gute Möglichkeit, Ressourcen und Größenqualifizierer zu verwenden .
Fügen Sie diese Bool-Ressource in res / values als bools.xml oder was auch immer ein (Dateinamen spielen hier keine Rolle):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
Fügen Sie dieses in res / values-sw600dp und res / values-xlarge ein:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
In dieser ergänzenden Antwort finden Sie Hilfe zum Hinzufügen dieser Verzeichnisse und Dateien in Android Studio.
In der onCreate-Methode Ihrer Aktivitäten können Sie Folgendes tun:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Vorrichtungen , die mehr als 600 dp in der kleinsten Breitenrichtung sind, oder x-large auf vorge Android 3.2 Geräte (Tabletten, im Grunde) werden wie normale Verhalten, basierend auf Sensor und benutzer verriegelte Drehung, etc . Alles andere (Telefone, so ziemlich) wird nur im Hochformat sein.
xlarge
oder kann ich nur verwenden sw600dp
? Es gibt heutzutage wahrscheinlich keine Tablets mit <3,2.
onCreate()
. Als ich den Anruf setRequestedOrientation()
in Zeit und Kontext an eine andere Position verschoben habe , fand der Neustart nicht mehr statt.
Sie können auf diese Weise versuchen, zuerst die Bildschirmgröße des Geräts zu ermitteln
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
Toast.makeText(this, "Large screen",Toast.LENGTH_LONG).show();
}
else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
Toast.makeText(this, "Normal sized screen" , Toast.LENGTH_LONG).show();
}
else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
Toast.makeText(this, "Small sized screen" , Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, "Screen size is neither large, normal or small" , Toast.LENGTH_LONG).show();
}
und dann die Ausrichtung entsprechend einstellen
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Configuration
liefert screenLayout
Informationen - DPI. Während sich die Frage auf die Bildschirmgröße des physischen Geräts bezieht - Telefon VS Tablet. Das heißt, Sie können ein Configuration.SCREENLAYOUT_SIZE_NORMAL
und es wäre ein MDPI-Tablet.
In Android Studio können Sie die folgenden Schritte ausführen, um die Verzeichnisse res/values-sw600dp
und res/values-large
mit ihren bools.xml
Dateien hinzuzufügen .
Wählen Sie zunächst auf der Registerkarte Projekt im Navigator den Filter Projekt (anstelle von Android) aus.
Klicken Sie dann mit der rechten Maustaste auf das app/src/main/res
Verzeichnis. Wählen Sie " Neu" > " Android-Ressourcenverzeichnis" .
Wählen Sie Kleinste Bildschirmbreite und drücken Sie die Taste >> .
Geben Sie 600
für die kleinste Bildschirmbreite ein. Der Verzeichnisname wird automatisch generiert. Sag OK.
Klicken Sie dann mit der rechten Maustaste auf die neu erstellte values-sw600dp
Datei. Wählen Sie " Neu" > " Werte" . Geben Sie bools
den Namen ein.
Das Hinzufügen eines values-large
Verzeichnisses ist nur erforderlich, wenn Sie vor Android 3.2 (API-Stufe 13) unterstützen. Andernfalls können Sie diesen Schritt überspringen. Das values-large
Verzeichnis entspricht values-sw600dp
. ((values-xlarge
entspricht values-sw720dp
.)
Führen Sie zum Erstellen des values-large
Verzeichnisses die gleichen Schritte wie oben aus. Wählen Sie in diesem Fall jedoch Größe anstelle der kleinsten Bildschirmbreite. Wählen Sie Groß . Der Verzeichnisname wird automatisch generiert.
Klicken Sie wie zuvor mit der rechten Maustaste auf das Verzeichnis, um die bools.xml
Datei zu erstellen .
So habe ich es gemacht (inspiriert von http://androidblogger.blogspot.com/2011/08/orientation-for-both-phones-and-tablets.html ):
In AndroidManifest.xml müssen Sie für jede Aktivität, die Sie zwischen Hoch- und Querformat wechseln möchten (stellen Sie sicher, dass Sie screenSize hinzufügen - dies wurde früher nicht benötigt!). Hier müssen Sie keine Bildschirmausrichtung festlegen. ::
android:configChanges="keyboardHidden|orientation|screenSize"
Methoden zum Hinzufügen zu jeder Aktivität:
public static boolean isXLargeScreen(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
und: (Wenn Sie diese Methode nicht überschreiben, ruft die App beim Ändern der Ausrichtung onCreate () auf.)
@Override
public void onConfigurationChanged (Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (!isXLargeScreen(getApplicationContext()) ) {
return; //keep in portrait mode if a phone
}
//I set background images for landscape and portrait here
}
In onCreate () jeder Aktivität:
if (!isXLargeScreen(getApplicationContext())) { //set phones to portrait;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else {
//I set background images here depending on portrait or landscape orientation
}
Das einzige, was ich anscheinend nicht herausfinden kann, ist, wie ich die App dazu bringen kann, Layoutdateien zu ändern, wenn ich von Querformat zu Hochformat oder umgekehrt wechsle. Ich gehe davon aus, dass die Antwort etwas Ähnliches tut wie der obige Link, aber ich konnte das nicht für mich zum Laufen bringen - es hat alle meine Daten gelöscht. Wenn Sie jedoch eine App haben, die so einfach ist, dass Sie dieselbe Layoutdatei für Hoch- und Querformat haben, sollte dies funktionieren.
Nach Ginnys Antwort denke ich, dass der zuverlässigste Weg dies ist:
Fügen Sie wie hier beschrieben einen Booleschen Wert in die Ressourcen sw600dp ein. Es muss das Präfix sw haben, sonst funktioniert es nicht richtig:
in res / values-sw600dp / dimension.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
in res / values / dimension.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">false</bool>
</resources>
Erstellen Sie dann eine Methode, um diesen Booleschen Wert abzurufen:
public class ViewUtils {
public static boolean isTablet(Context context){
return context.getResources().getBoolean(R.bool.isTablet);
}
}
Und eine Basisaktivität, die sich von den Aktivitäten erstreckt, bei denen Sie dieses Verhalten wünschen:
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!ViewUtils.isTablet(this)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}
Jede Aktivität würde also BaseActivity erweitern:
public class LoginActivity extends BaseActivity //....
Wichtig : Auch wenn Sie von erweitern BaseActivity
, müssen Sie die Zeile in Ihrer AndroidManifest.xml android:configChanges="orientation|screenSize"
zu jeder Zeile Activity
hinzufügen:
<activity
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
Nun, das ist etwas spät, aber hier ist eine reine XML- Lösung, aber eine Hack-Lösung, die keine Aktivität als neu erstelltsetRequestedOrientation
ob sie die Ausrichtung ändern müsste:
Nach der akzeptierten Antwort füge ich die Kotlin-Datei mit der Lösung hinzu, die hoffentlich jemandem hilft
Fügen Sie diese Bool-Ressource res/values
als bools.xml oder was auch immer ein (Dateinamen spielen hier keine Rolle):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
Setzen Sie dieses ein res/values-sw600dp
und res/values-sw600dp-land
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
Fügen Sie es dann in Ihrer Aktivität oder Fragmentität in die folgenden Zeilen ein
class MyActivity : Activity() {
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
if (resources.getBoolean(R.bool.portrait_only)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
super.onCreate(savedInstanceState)
}
@SuppressLint("SourceLockedOrientationActivity")
override fun onConfigurationChanged(newConfig: Configuration) {
if (resources.getBoolean(R.bool.portrait_only)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
super.onConfigurationChanged(newConfig)
}
}
Andere Lösungen haben bei mir nicht funktioniert. Ich hatte immer noch ein seltsames Orientierungsproblem mit Dialogen und Erholungsproblemen. Meine Lösung bestand darin, die Aktivität zu erweitern und sie als Porträt im Manifest zu erzwingen.
Beispiel:
public class MainActivityPhone extends MainActivity {}
manifest.xml:
<activity
android:screenOrientation="portrait"
android:name=".MainActivityPhone"
android:theme="@style/AppTheme.NoActionBar" />
in Splashcreen-Aktivität:
Intent i = null;
boolean isTablet = getResources().getBoolean(R.bool.is_tablet);
if (!isTablet)
i = new Intent(this, MainActivityPhone.class);
else
i = new Intent(this, MainActivity.class);
startActivity(i);
Alte Frage, die ich kenne. Um Ihre App immer im Hochformat auszuführen, auch wenn die Ausrichtung geändert werden kann oder wird usw. (z. B. auf Tablets), habe ich diese Funktion entwickelt, mit der das Gerät in die richtige Ausrichtung gebracht wird, ohne dass Sie wissen müssen, wie das Hoch- und Querformat ist Funktionen sind auf dem Gerät organisiert.
private void initActivityScreenOrientPortrait()
{
// Avoid screen rotations (use the manifests android:screenOrientation setting)
// Set this to nosensor or potrait
// Set window fullscreen
this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
DisplayMetrics metrics = new DisplayMetrics();
this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// Test if it is VISUAL in portrait mode by simply checking it's size
boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels );
if( !bIsVisualPortrait )
{
// Swap the orientation to match the VISUAL portrait mode
if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
{ this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); }
else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); }
}
else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); }
}
Klappt wunderbar!
HINWEIS: Ändern Sie this.activity
durch Ihre Aktivität oder fügen Sie es der Hauptaktivität hinzu und entfernen Sie this.activity
;-)
Wenn Sie das Gegenteil tun möchten, müssen Sie den Code in Querformat ändern (aber ich denke, es ist klar, wie das geht).
Leider führt die Verwendung der Methode setRequestedOrientation (...) dazu, dass die Aktivität neu gestartet wird. Selbst wenn Sie dies in der onCreate-Methode aufrufen, durchläuft sie den Aktivitätslebenszyklus und erstellt dann dieselbe Aktivität in der angeforderten Ausrichtung neu. Bei der Antwort von @Brian Christensen sollten Sie berücksichtigen, dass der Aktivitätscode möglicherweise zweimal aufgerufen wird. Dies kann negative Auswirkungen haben (nicht nur visuell, sondern auch bei Netzwerkanforderungen, Analysen usw.).
Darüber hinaus ist das Festlegen des configChanges-Attributs im Manifest meiner Meinung nach ein großer Kompromiss, der massive Refactoring-Kosten verursachen könnte. Android-Entwickler empfehlen nicht, dieses Attribut zu ändern .
Schließlich ist der Versuch, die screenOrientation irgendwie anders einzustellen (um das Problem des Neustarts zu vermeiden) unmöglich, statisch unmöglich, da das statische Manifest nicht geändert werden kann. Programmatisch ist es nur möglich, diese Methode in der bereits gestarteten Aktivität aufzurufen.
Zusammenfassung: Meiner Meinung nach ist der Vorschlag von @Brian Christensen der beste Kompromiss, aber beachten Sie das Problem der Neustartaktivität.
layout-land
innerhalb desres
Ordners der Fall ist .