Liste ayrıntısı düzeni oluşturma

List-detail, bir bölmenin öğe listesini sunduğu ve başka bir bölmenin listeden seçilen öğelerin ayrıntılarını görüntülediği çift bölmeli bir düzenden oluşan bir kullanıcı arayüzü kalıbıdır.

Bu kalıp özellikle büyük koleksiyonların öğeleri hakkında ayrıntılı bilgiler sağlayan uygulamalar için faydalıdır. Örneğin, e-posta listesi ve her e-posta iletisinin ayrıntılı içeriğini içeren bir e-posta istemcisi gibi. Liste ayrıntıları, uygulama tercihlerini ayrıntı bölmesinde her bir kategorinin tercihlerini içeren bir kategori listesine bölme gibi daha az kritik yollar için de kullanılabilir.

ListDetailPaneScaffold ile kullanıcı arayüzü kalıbı uygula

ListDetailPaneScaffold, uygulamanızdaki liste ayrıntısı kalıbının uygulanmasını kolaylaştıran bir composable'dır. Liste ayrıntısı iskelesi en fazla üç bölmeden oluşabilir: liste bölmesi, ayrıntı bölmesi ve isteğe bağlı ekstra bölme. İskele, ekran alanı hesaplamalarını işler. Yeterli ekran boyutu mevcut olduğunda, liste bölmesinin yanında ayrıntı bölmesi gösterilir. Küçük ekran boyutlarında, yapı otomatik olarak liste veya ayrıntı bölmesini tam ekran görüntülemeye geçiş yapar.

Liste sayfasının yanında gösterilen bir ayrıntı bölmesi.
Şekil 1. Yeterli ekran boyutu mevcut olduğunda, liste bölmesinin yanında ayrıntı bölmesi gösterilir.
Bir öğe seçildikten sonra, ayrıntı bölmesi ekranın tamamını kaplar.
Şekil 2. Ekran boyutu sınırlı olduğunda ayrıntı bölmesi (bir öğe seçildiği için) tüm alanı kaplar.

Bağımlılıkları bildirme

ListDetailPaneScaffold, Material 3 uyarlanabilir kitaplığının bir parçasıdır. Uygulamanızın veya modülünüzün build.gradle dosyasında kitaplık için bir bağımlılık ekleyin:

implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-alpha07")
implementation("androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha07")
implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha07")

Temel kullanım

Aşağıda ListDetailPaneScaffold ile ilgili temel kullanım gösterilmektedir:

  1. Listedeki seçili öğeyi değişken bir durum değişkeninde depolayın. Değişken, ayrıntı bölmesinde gösterilecek öğeyi tutar. Genellikle, şu anda seçili olan öğeyi null ile başlatmak istersiniz. Bu, henüz bir seçim yapılmadığını gösterir.

    class MyItem(val id: Int) {
        companion object {
            val Saver: Saver<MyItem?, Int> = Saver(
                { it?.id },
                ::MyItem,
            )
        }
    }

    var selectedItem: MyItem? by rememberSaveable(stateSaver = MyItem.Saver) {
        mutableStateOf(null)
    }

  2. rememberListDetailPaneScaffoldNavigator ile ThreePaneScaffoldNavigator oluşturun ve BackHandler ekleyin. Bu gezgin; liste, ayrıntı ve ekstra bölmeler arasında hareket etmek ve yapıya durumu sağlamak için kullanılır. Eklenen BackHandler, sistem geri hareketini veya düğmesini kullanarak geri gitme desteği sağlar. ListDetailPaneScaffold için geri düğmesinin beklenen davranışı, pencere boyutuna ve mevcut yapı iskelet değerine bağlıdır. ListDetailPaneScaffold, mevcut duruma geri dönmeyi destekliyorsa canNavigateBack(), true olur ve BackHandler etkinleştirilir.

    val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>()
    
    BackHandler(navigator.canNavigateBack()) {
        navigator.navigateBack()
    }

  3. Oluşturduğunuz navigator öğesinden scaffoldState öğesini ListDetailPaneScaffold composable'a iletin.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        // ...
    )

  4. Liste bölmesi uygulamanızı ListDetailPaneScaffold öğesine sağlayın. Uygulamanızın, yeni seçilen öğeyi yakalamak için bir geri çağırma bağımsız değişkeni içerdiğinden emin olun. Bu geri çağırma tetiklendiğinde, selectedItem durum değişkenini güncelleyin ve ayrıntı bölmesini (ListDetailPaneScaffoldRole.Detail) görüntülemek için ThreePaneScaffoldNavigator değerini kullanın.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            AnimatedPane(Modifier) {
                MyList(
                    onItemClick = { id ->
                        // Set current item
                        selectedItem = id
                        // Switch focus to detail pane
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
                    }
                )
            }
        },
        // ...
    )

  5. Ayrıntı bölmesi uygulamanızı ListDetailPaneScaffold özelliğine dahil edin. Yalnızca selectedItem boş değilse ayrıntı içeriğini görüntüleyin.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane =
        // ...
        detailPane = {
            AnimatedPane(Modifier) {
                selectedItem?.let { item ->
                    MyDetails(item)
                }
            }
        },
    )

Yukarıdaki adımları uyguladıktan sonra, kodunuz şunun gibi görünecektir:

// Currently selected item
var selectedItem: MyItem? by rememberSaveable(stateSaver = MyItem.Saver) {
    mutableStateOf(null)
}

// Create the ListDetailPaneScaffoldState
val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>()

BackHandler(navigator.canNavigateBack()) {
    navigator.navigateBack()
}

ListDetailPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    listPane = {
        AnimatedPane(Modifier) {
            MyList(
                onItemClick = { id ->
                    // Set current item
                    selectedItem = id
                    // Display the detail pane
                    navigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
                },
            )
        }
    },
    detailPane = {
        AnimatedPane(Modifier) {
            // Show the detail pane content if selected item is available
            selectedItem?.let { item ->
                MyDetails(item)
            }
        }
    },
)