Duyarlı kullanıcı arayüzü ve gezinme
Kullanıcılarınıza mümkün olan en iyi gezinme deneyimini sunmak için kullanıcı cihazının genişliğine, yüksekliğine ve en küçük genişliğine göre uyarlanmış bir gezinme kullanıcı arayüzü sağlamanız gerekir. Alt uygulama çubuğu, her zaman var olan veya daraltılabilir bir gezinme çekmecesi, ray veya mevcut ekran alanına ve uygulamanızın benzersiz stiline bağlı olarak tamamen yeni bir şey kullanmak isteyebilirsiniz.
Materyal tasarım ürün mimarisi kılavuzu, duyarlı bir kullanıcı arayüzü (çevresel değişikliklere dinamik olarak uyum sağlayan bir kullanıcı arayüzü) oluşturmak için ek bağlam ve dikkat edilmesi gereken noktalar sağlar. Çevresel değişikliklere örnek olarak genişlik, yükseklik, yön ve kullanıcının dil tercihinde yapılan ayarlamalar verilebilir. Bu çevresel özellikleri topluca cihazın yapılandırması olarak adlandırılır.
Çalışma zamanında bu özelliklerden biri veya daha fazlası değiştiğinde Android OS, uygulamanızın etkinliklerini ve parçalarını yok edip yeniden oluşturarak yanıt verir. Bu nedenle, Android'de duyarlı bir kullanıcı arayüzünü desteklemek için yapabileceğiniz en iyi şey, uygun yerlerde kaynak yapılandırma niteleyicilerini kullandığınızdan emin olmak ve sabit kodlu düzen boyutlarını kullanmaktan kaçınmaktır.
Duyarlı bir kullanıcı arayüzünde genel gezinme uygulama
Genel gezinmeyi duyarlı bir kullanıcı arayüzünün parçası olarak uygulamak, gezinme grafiğinizi barındıran etkinlikle başlar. Uygulamalı bir örnek için Navigasyon codelab'e göz atın.
Codelab, Şekil 2'de gösterildiği gibi gezinme menüsünü görüntülemek için bir NavigationView
kullanır. Bu NavigationView
, en az 960 dp genişlikte oluşturulan bir cihazda çalıştırıldığında her zaman ekranda kalır.
Diğer cihaz boyutları ve yönleri, gerektiğinde DrawerLayout
veya BottomNavigationView
arasında dinamik olarak geçiş yapar.
Bu davranışı, her bir düzenin istenen gezinme öğelerini tanımladığı ve mevcut cihaz yapılandırmasına dayalı olarak hiyerarşiyi görüntülediği üç farklı düzen oluşturarak uygulayabilirsiniz.
Her bir düzenin uygulanacağı yapılandırma, düzen dosyasının yerleştirildiği dizin yapısıyla belirlenir. Örneğin, NavigationView
düzen dosyası res/layout-w960dp
dizininde bulunur.
<!-- 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>
Alt gezinme görünümü res/layout-h470dp
dizininde bulunur:
<!-- 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>
Çekmece düzeni res/layout
dizininde bulunur. Yapılandırmaya özel niteleyici içermeyen varsayılan düzenler için bu dizini kullanın:
<!-- 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, hangi kaynakları uygulayacağını belirlerken bir öncelik sırası izler. Bu örneğe özel olarak, -w960dp
(veya kullanılabilir genişlik >= 960 dp), -h470dp
(veya kullanılabilir yükseklik >= 470) değerine göre önceliklidir. Cihaz yapılandırması bu koşullardan herhangi biriyle eşleşmezse varsayılan düzen kaynağı (res/layout/navigation_activity.xml
) kullanılır.
Gezinme etkinliklerini işlerken, aşağıdaki örnekte gösterildiği gibi yalnızca mevcut widget'lara karşılık gelen etkinlikleri bağlamanız gerekir.
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); } } }
Cihaz yapılandırması değişirse, başka bir şekilde yapılandırılmadığı sürece Android, önceki yapılandırmadaki etkinliği ilişkili görünümleriyle birlikte kaldırır. Ardından, yeni yapılandırma için tasarlanan kaynaklarla etkinliği yeniden oluşturur. Yıkılıp yeniden oluşturulan etkinlik, onCreate()
içindeki uygun genel gezinme öğelerini otomatik olarak bağlar.
Bölünmüş görünüm düzenlerinin alternatiflerini değerlendirin
Bölünmüş görünüm düzenleri veya ana/ayrıntılı düzenler, bir zamanlar tabletler ve diğer büyük ekranlı cihazlar için tasarım yapmanın çok popüler ve önerilen bir yoluydu.
Android tabletlerin piyasaya sürüldüğünden beri cihaz ekosistemi hızla büyüdü. Büyük ekranlı cihazların tasarım alanını önemli ölçüde etkileyen faktörlerden biri de çok pencereli modların, özellikle de ChromeOS cihazlardakiler gibi tamamen yeniden boyutlandırılabilir olan serbest biçimli pencerelerdir. Bu yaklaşım, gezinme yapınızı ekran boyutuna göre değiştirmek yerine uygulamanızın her ekranının duyarlı olmasına çok daha fazla önem verir.
Gezinme kitaplığını kullanarak bölünmüş görünümlü düzen arayüzü uygulamak mümkün olsa da diğer alternatifleri de değerlendirmeniz gerekir.
Hedef adları
Grafiğinizde android:label
özelliğini kullanarak hedef adları sağlarsanız içeriğinizin yine de yerelleştirilebilmesi için her zaman kaynak değerleri kullandığınızdan emin olun.
<navigation ...>
<fragment
android:id="@+id/my_dest"
android:name="com.example.MyFragment"
android:label="@string/my_dest_label"
tools:layout="@layout/my_fragment" />
...
Kaynak değerleriyle, yapılandırmanız her değiştiğinde hedeflerinize otomatik olarak en uygun kaynaklar uygulanır.