Responsive Benutzeroberfläche und Navigation
Um Ihren Nutzern die bestmögliche Navigation zu bieten, sollten Sie eine Navigations-UI bereitstellen, die auf die Breite, Höhe und die kleinste Breite des Geräts ist. Sie können auch ein untere App-Leiste immer vorhanden oder minimierbar Navigationsleiste, ein Bahn oder vielleicht auch etwas völlig Neues, das auf dem verfügbaren Bildschirm den einzigartigen Stil der App.
<ph type="x-smartling-placeholder">Das Material Design Leitfaden zur Produktarchitektur bietet zusätzlichen Kontext und Überlegungen zum Erstellen einer responsiven UI, die eine Benutzeroberfläche, die sich dynamisch an Umgebungsänderungen anpasst. Einige Beispiele für Dazu gehören Anpassungen von Breite, Höhe, Ausrichtung und Spracheinstellung des Nutzers. Diese Umwelteigenschaften sind kollektiv Dies wird als Konfiguration des Geräts bezeichnet.
Wenn sich mindestens eines dieser Eigenschaften während der Laufzeit ändert, reagiert das Android-Betriebssystem von Zerstören und anschließendes Neuerstellen der Aktivitäten und Fragmente Ihrer App. Daher sollten Sie zur Unterstützung einer responsiven UI unter Android dass Sie das richtige Qualifier für Ressourcenkonfiguration und gegebenenfalls vermeiden der Verwendung hartcodierter Layoutgrößen.
Globale Navigation in einer responsiven UI implementieren
Die Implementierung der globalen Navigation als Teil einer responsiven UI beginnt mit dem
Aktivität, in der Ihr Navigationsdiagramm gehostet wird. Ein praktisches Beispiel finden Sie
die
Codelab zur Navigation.
Im Codelab wird ein NavigationView
-
um das Navigationsmenü anzuzeigen (siehe Abbildung 2). Bei Ausführung auf einem Gerät
das bei einer Breite von mindestens 960 dp gerendert wird, ist dieses NavigationView
immer
zu präsentieren.
Andere Gerätegrößen und -ausrichtungen wechseln dynamisch zwischen
DrawerLayout
oder
BottomNavigationView
nach Bedarf anpassen.
Sie können dieses Verhalten implementieren, indem Sie drei verschiedene Layouts erstellen, in denen jedes Layout definiert die gewünschten Navigationselemente und die Ansichtshierarchie basierend auf dem aktuelle Gerätekonfiguration
Die Konfiguration, für die die einzelnen Layouts gelten, wird durch das Verzeichnis
Struktur, in der die Layoutdatei platziert wird. Beispiel: NavigationView
Die Layoutdatei befindet sich im Verzeichnis res/layout-w960dp
.
<!-- res/layout-w960dp/navigation_activity.xml -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.codelabs.navigation.MainActivity">
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
app:elevation="0dp"
app:headerLayout="@layout/nav_view_header"
app:menu="@menu/nav_drawer_menu" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_toEndOf="@id/nav_view"
android:background="?android:attr/listDivider" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="@id/nav_view"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:layout_toEndOf="@id/nav_view"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
</RelativeLayout>
Die untere Navigationsansicht befindet sich im Verzeichnis res/layout-h470dp
:
<!-- res/layout-h470dp/navigation_activity.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.codelabs.navigation.MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu" />
</LinearLayout>
Das Leistenlayout befindet sich im Verzeichnis res/layout
. Dieses Verzeichnis verwenden für
Standardlayouts ohne konfigurationsspezifische Qualifier:
<!-- res/layout/navigation_activity.xml -->
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.codelabs.navigation.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
Android folgt einer
Prioritätsreihenfolge
bei der Entscheidung, welche Ressourcen
angewandt werden sollen. Spezifisch in diesem Beispiel: -w960dp
(oder die verfügbare Breite ≥ 960 dp) hat Vorrang vor -h470dp
(oder den verfügbaren
Höhe >= 470). Wenn die Gerätekonfiguration mit keiner dieser Einstellungen übereinstimmt
dann wird die Standard-Layoutressource
(res/layout/navigation_activity.xml
) wird verwendet.
Für die Verarbeitung von Navigationsereignissen müssen Sie nur die Ereignisse verknüpfen, die zu den derzeit vorhandenen Widgets hinzu, wie im folgenden Beispiel gezeigt.
Kotlin
class MainActivity : AppCompatActivity() { private lateinit var appBarConfiguration : AppBarConfiguration override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.navigation_activity) val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout) appBarConfiguration = AppBarConfiguration( setOf(R.id.home_dest, R.id.deeplink_dest), drawerLayout) ... // Initialize the app bar with the navigation drawer if present. // If the drawerLayout is not null here, a Navigation button will be added // to the app bar whenever the user is on a top-level destination. setupActionBarWithNavController(navController, appBarConfig) // Initialize the NavigationView if it is present, // so that clicking an item takes // the user to the appropriate destination. val sideNavView = findViewById<NavigationView>(R.id.nav_view) sideNavView?.setupWithNavController(navController) // Initialize the BottomNavigationView if it is present, // so that clicking an item takes // the user to the appropriate destination. val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav_view) bottomNav?.setupWithNavController(navController) ... } ... }
Java
public class MainActivity extends AppCompatActivity { private AppBarConfiguration appBarConfiguration; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.navigation_activity); NavHostFragment host = (NavHostFragment) getSupportFragmentManager() .findFragmentById(R.id.my_nav_host_fragment); NavController navController = host.getNavController(); DrawerLayout drawerLayout = findViewById(R.id.drawer_layout); appBarConfiguration = new AppBarConfiguration.Builder( R.id.home_dest, R.id.deeplink_dest) .setDrawerLayout(drawerLayout) .build(); // Initialize the app bar with the navigation drawer if present. // If the drawerLayout is not null here, a Navigation button will be added to // the app bar whenever the user is on a top-level destination. NavigationUI.setupActionBarWithNavController( this, navController, appBarConfiguration); // Initialize the NavigationView if it is present, // so that clicking an item takes // the user to the appropriate destination. NavigationView sideNavView = findViewById(R.id.nav_view); if(sideNavView != null) { NavigationUI.setupWithNavController(sideNavView, navController); } // Initialize the BottomNavigationView if it is present, // so that clicking an item takes // the user to the appropriate destination. BottomNavigationView bottomNav = findViewById(R.id.bottom_nav_view); if(bottomNav != null) { NavigationUI.setupWithNavController(bottomNav, navController); } } }
Wenn sich die Gerätekonfiguration ändert, es sei denn,
nicht anders konfiguriert,
Android löscht die Aktivität aus der vorherigen Konfiguration sowie
zugehörigen Datenansichten. Anschließend wird die Aktivität mit Ressourcen nachgestellt, die für die
neue Konfiguration. Wenn die Aktivität zerstört und neu erstellt wird,
wird automatisch die richtigen globalen Navigationselemente in onCreate()
verbunden.
Alternativen zur geteilten Ansicht erwägen
Split View-Layouts oder Master-/Detail-Layouts wurden eine sehr beliebte und empfohlene Methode zur Entwicklung von Designs für Tablets und andere große Bildschirme. Geräte.
Seit der Einführung von Android-Tablets ist das Angebot an Geräten gewachsen. schnell ändern. Ein Faktor, der den Designraum für große wurde der Mehrfenstermodus eingeführt, Freiform-Fenster, deren Größe vollständig angepasst werden kann, wie z. B. auf ChromeOS-Geräten. Dadurch wird jeder Bildschirm Ihrer App responsiv, anstatt die Navigationsstruktur je nach Bildschirm Größe.
Es ist zwar möglich, eine Layout-Oberfläche für eine geteilte Ansicht mithilfe von Navigationsbibliothek verwenden, sollten Sie andere Alternativen in Betracht ziehen.
Zielnamen
Wenn Sie Zielnamen in der Grafik mithilfe der android:label
verwenden Sie immer Ressourcenwerte, damit Ihre Inhalte
lokalisiert werden.
<navigation ...>
<fragment
android:id="@+id/my_dest"
android:name="com.example.MyFragment"
android:label="@string/my_dest_label"
tools:layout="@layout/my_fragment" />
...
Mit Ressourcenwerten haben Ihre Ziele automatisch die am besten geeigneten die angewendet werden, wenn sich Ihre Konfiguration ändert.