Kullanıcı arayüzü katmanı

Kullanıcı arayüzünün rolü, uygulama verilerini ekranda göstermek ve kullanıcı etkileşiminin temel noktası işlevi görür. Veriler her değiştiğinde, Bunun nedeni kullanıcı etkileşimi (ör. bir düğmeye basma) veya harici giriş (ör. bir ağ yanıtı olduğunda) kullanıcı arayüzü bu değişiklikleri yansıtacak şekilde güncellenmelidir. Kullanıcı arayüzü, uygulama durumunun görsel bir temsilidir. veri katmanından alınır.

Ancak veri katmanından aldığınız uygulama verileri genellikle bir gerekenden farklı bir biçimde olması gerekir. Örneğin, kullanıcı arayüzüne yönelik verilerin yalnızca bir kısmına ihtiyaç duyabilir veya iki kullanıcı için alakalı bilgiler sunmak üzere farklı veri kaynakları kullanır. Uyguladığınız mantık ne olursa olsun, tüm bilgileri kullanıcı arayüzüne aktarmanız gerekir. tam olarak oluşturulması gerekir. Kullanıcı arayüzü katmanı, uygulama verileri, kullanıcı arayüzünün sunabileceği bir forma dönüşür ve ardından eder.

Tipik bir mimaride, kullanıcı arayüzü katmanının kullanıcı arayüzü öğeleri duruma bağlıdır.
    Bu da veri katmanı veya veri katmanı
    isteğe bağlı alan adı katmanından yararlanabilirsiniz.
Şekil 1. Uygulama mimarisindeki kullanıcı arayüzü katmanının rolü.
ziyaret edin.

Temel örnek olay

Kullanıcının okuması için haber makaleleri getiren bir uygulama düşünün. Uygulamada makalelerin sunulduğu makale ekranı da gösterilir ve oturum açmış kullanıcıların gerçekten göze çarpan makalelere yer işareti koymalarına olanak tanır. Her halükarda çok sayıda makaleye göz atarken okuyucu, kategorileri görebilirsiniz. Özetle, uygulama kullanıcıların aşağıdakileri yapmasına olanak tanır:

  • Okunabilecek makaleleri görüntüleyin.
  • Makalelere kategoriye göre göz atın.
  • Oturum açın ve belirli makalelere yer işareti koyun.
  • Uygun durumlarda bazı ücretli özelliklere erişebilirsiniz.
ziyaret edin.
Şekil 2. Kullanıcı arayüzü örnek olayı için örnek haber uygulaması.

Aşağıdaki bölümlerde, bu örnek bir örnek olay olarak kullanılmaktadır: ve problemlere değinmenin yanı sıra, iki yönlü veri akışı için bu ilkelerin kullanıcı arayüzüne yönelik uygulama mimarisi bağlamında çözülmeye katmanıdır.

Kullanıcı arayüzü katmanı mimarisi

UI terimi, etkinlikler ve bunu yapmak için kullandıkları API'lerden bağımsız olarak verileri görüntülemelerine Jetpack Compose). Çünkü verilerin rolü, verilerin katmanın etiketi, erişimi korumak, yönetmek ve kullanıcı arayüzü katmanı aşağıdaki adımları gerçekleştirmelidir:

  1. Uygulama verilerini tüketme ve kullanıcı arayüzünün kolayca oluşturabileceği verilere dönüştürme.
  2. Kullanıcı arayüzünde oluşturulabilir verileri tüketme ve bu verileri sunum için kullanıcı arayüzü öğelerine dönüştürme kullanıcıya gösterir.
  3. Bir araya getirilen kullanıcı arayüzü öğelerinden gelen kullanıcı girişi etkinliklerini kullanır ve bunları yansıtır. bu değişiklikleri kullanıcı arayüzü verilerinde
  4. 1-3. adımları gerektiği kadar tekrarlayın.

Bu kılavuzun geri kalanında, yüksek performans gösteren bir kullanıcı arayüzü katmanının bu adımları uygulayın. Bu kılavuz özellikle aşağıdaki görevleri ve kavramları kapsar:

  • Kullanıcı arayüzü durumu nasıl tanımlanır?
  • Kullanıcı arayüzünü oluşturma ve yönetme yöntemi olarak tek yönlü veri akışı (UDF) durumu.
  • UDF ilkelerine göre gözlemlenebilir veri türleriyle kullanıcı arayüzü durumunu gösterme.
  • Gözlemlenebilir kullanıcı arayüzü durumunu tüketen kullanıcı arayüzü uygulama.

Bunların en temeli, kullanıcı arayüzü durumunun tanımıdır.

Kullanıcı arayüzü durumunu tanımla

Daha önce özetlenen örnek olayı inceleyin. Kısacası, kullanıcı arayüzü sayesinde makale listesi ve her makale için meta veriler ekleyebilirsiniz. Bu bilgiler uygulamanın kullanıcıya sunduğu, kullanıcı arayüzü durumudur.

Başka bir deyişle: Kullanıcı arayüzü, kullanıcının gördüğü gibiyse, kullanıcı arayüzü durumu, uygulamanın ne olduğunu belirtir. diyor. Aynı paranın iki yüzü gibi, kullanıcı arayüzü de görseldir. temsilidir. Kullanıcı arayüzü durumunda yapılan değişiklikler hemen yansıtılacak.

Kullanıcı arayüzü, ekrandaki kullanıcı arayüzü durumuyla bağlama kullanıcı arayüzü öğelerinin bir sonucudur.
Şekil 3. Kullanıcı arayüzü, ekrandaki kullanıcı arayüzü öğelerinin Kullanıcı arayüzü durumu.

Vaka analizini düşünün: Google Haberler uygulamasının gereksinimlerini karşılamak için kullanıcı arayüzünü tam olarak oluşturmak için gereken bilgiler NewsUiState veri sınıfı aşağıdaki şekilde tanımlanmıştır:

data class NewsUiState(
    val isSignedIn: Boolean = false,
    val isPremium: Boolean = false,
    val newsItems: List<NewsItemUiState> = listOf(),
    val userMessages: List<Message> = listOf()
)

data class NewsItemUiState(
    val title: String,
    val body: String,
    val bookmarked: Boolean = false,
    ...
)

Sabitlik

Yukarıdaki örnekte kullanıcı arayüzü durumu tanımı sabittir. Projenin en önemli faydası değişmeyen nesneler, nesnenin durumu hakkında garantiler israfa yol açabilir. Böylece, kullanıcı arayüzü tek bir öğeye odaklanmak için role: durumu okumak ve kullanıcı arayüzü öğelerini uygun şekilde güncellemek için. Bunun sonucunda, Kullanıcı arayüzünün kendisi veri kaynağı hâline getirmelidir. Bu ilkenin ihlal edilmesi, bir doğruluk kontrolü yaparak veri tutarsızlıklarına fark edebilirsiniz.

Örneğin, kullanıcı arayüzündeki bir NewsItemUiState nesnesinde bookmarked işareti varsa örnek olaydaki eyalet Activity sınıfında güncellendiyse, bu işaret bir veri katmanının yer işareti koyulan durumunun kaynağı olarak, makalesine göz atın. Sabit veri sınıfları, bu tür durumların önlenmesinde ve olmalıdır.

Bu kılavuzdaki adlandırma kuralları

Bu kılavuzda, kullanıcı arayüzü durumu sınıfları açıkladıklarını görür. Kural aşağıdaki gibidir:

İşlevler + UiState.

Örneğin, haberlerin gösterildiği bir ekranın durumu NewsUiState ise haber öğeleri listesindeki bir haber öğesinin durumu NewsItemUiState.

Tek Yönlü Veri Akışı ile durumu yönetme

Önceki bölümde, kullanıcı arayüzü durumunun sabit bir anlık görüntü kullanıcı arayüzünün oluşturulması için gereken ayrıntılar. Ancak Google Cloud'daki verilerin dinamik doğası bu durumun zamanla değişebileceği anlamına gelir. Bunun nedeni kullanıcı olabilir kullanılan temel verileri değiştiren etkileşimleri veya diğer etkinlikleri uygulamayı doldurabilirsiniz.

Bu etkileşimler, aracı tarafından işleme konmasında ve gerekli dönüşümleri gerçekleştirmesi için her etkinliğe uygulanacak yedek veri kaynaklarına ekleyerek kullanıcı arayüzü durumu oluşturun. Bu etkileşimler ve mantığı, kullanıcı arayüzünün kendisinde yer alabilir, ancak bu durum, kullanıcı arayüzü, adının verdiğinden daha fazlasını sunmaya başlar: veri sahibi olur, prodüktör, transformatör ve çok daha fazlasıdır. Ayrıca, test edilebilirliği, Sonuçta ortaya çıkan kod, ayırt edilebilir hiçbir şey olmayan sıkı sıkıya bağlı bir amalgamdır. sınırlar. Sonuç olarak, kullanıcı arayüzü yükün azaltılmasından faydalanıyor. Aksi takdirde Kullanıcı arayüzü durumu çok basit. Kullanıcı arayüzünün yegane sorumluluğu kullanıcı arayüzü durumunu görüntüleyin.

Bu bölümde, bir mimari kalıbı olan Tek Yönlü Veri Akışı (UDF) bu sağlıklı sorumluluk ayrımının uygulanmasına yardımcı olur.

Eyalet sahipleri

UI durumunun üretiminden sorumlu olan ve mantığı kullananlara eyalet sahipleri denir. Eyalet sahipleri, kullanıcı arayüzü öğelerinin kapsamına bağlı olarak farklı boyutlarda alttaki uygulama gibi tek bir widget'tan hızlıca yönetebilirler. çubuğunu ekranın tamamına veya navigasyon hedefi.

İkinci durumda, tipik uygulama bir ViewModel'e bağlı olarak, gerekiyorsa basit bir sınıf yeterli olabilir. Google Haberler uygulaması örnek olayda, ilk başarılı örnek olarak NewsViewModel sınıfını durum tutucusunu kullanarak bu bölümde görüntülenen ekran için kullanıcı arayüzü durumunu oluşturabilirsiniz.

Kullanıcı arayüzü ve durumu arasında kod bağımlılığını modellemenin birçok yolu vardır edelim. Ancak, kullanıcı arayüzü ile ViewModel arasındaki etkileşim sınıfı, genellikle etkinlik girişi ve izleyen durum çıkışı olarak anlaşılabilir. ilişki aşağıdaki şemada gösterildiği gibi gösterilebilir:

Uygulama verileri, veri katmanından ViewModel&#39;e aktarılır. Kullanıcı arayüzü durumu
    ViewModel&#39;den kullanıcı arayüzü öğelerine geçer ve etkinlikler, kullanıcı arayüzünden
    öğelerini ViewModel&#39;e geri gönderir.
4. Şekil. UDF'nin uygulama mimarisinde nasıl çalıştığını gösteren şema.

Durumun aşağı ve etkinliklerin yukarı doğru aktığı desene tek yönlü veri akışı (UDF) Bu kalıbın uygulamaya olan etkileri mimarisi şöyledir:

  • ViewModel, kullanıcı arayüzü tarafından kullanılacak durumu tutar ve gösterir. Kullanıcı arayüzü durum, ViewModel tarafından dönüştürülen uygulama verileridir.
  • Kullanıcı arayüzü, kullanıcı etkinliklerinin ViewModel'ini bilgilendirir.
  • ViewModel, kullanıcı işlemlerini işler ve durumu günceller.
  • Güncellenen durum, oluşturulması için kullanıcı arayüzüne geri aktarılır.
  • Yukarıdaki durum, durum değişikliğine neden olan herhangi bir olay için tekrarlanır.

ViewModel, gezinme hedefleri veya ekranları için depolar veya kullanım alanı sınıflarını kullanarak verileri alıp kullanıcı arayüzü durumuna dönüştürebilirsiniz. durum değişikliklerine neden olabilecek olayların etkileriyle birlikte uygulanır. İlgili içeriği oluşturmak için kullanılan Daha önce bahsedilen örnek olay, her biri başlığı, açıklaması, kaynağı, yazar adı, yayın tarihi ve videoya yer işareti koyuldu. Her makale öğesinin kullanıcı arayüzü aşağıdaki gibi görünür:

5.Şekil Örnek olay uygulamasındaki bir makale öğesinin kullanıcı arayüzü.
ziyaret edin.

Bir makaleye yer işareti koymak isteyen bir kullanıcı, durum mutasyonlarına neden olur. Eyalet üreticisi olarak ViewModel'in tüm alanları doldurmak için gereken tüm mantığı tanımlama sorumluluğu durumunu değiştirebilir ve kullanıcı arayüzünün tam olarak oluşturulması için gereken etkinlikleri işleyebilirsiniz.

Kullanıcı bir öğeyi yer işaretlerine eklediğinde kullanıcı arayüzü etkinliği gerçekleşir. ViewModel
    veri katmanına durum değişikliğini bildirir. Veri katmanı,
    uygulama verilerini günceller. Yeni uygulama verileri:
    yer işareti konulan makale ViewModel&#39;e aktarılır ve daha sonra,
    yeni kullanıcı arayüzü durumuna geçirir ve bunu görüntülemek için kullanıcı arayüzü öğelerine iletir.
6. Şekil. UDF'deki etkinlik ve veri döngüsünü gösteren şema.

Aşağıdaki bölümlerde durum değişikliklerine neden olan olaylar daha ayrıntılı olarak ele alınmaktadır ve UDF kullanılarak nasıl işlendikleri üzerine konuşacağız.

Mantık türleri

Değer kazandırdığı için makalelere yer işareti koymak iş mantığına örnektir ekleyin. Bu konuda daha fazla bilgi için verilere bakın katman sayfasını etkinleştirmelisiniz. Ancak, kullanmak istediğiniz şu anlamlara gelir:

  • İş mantığı, uygulama için ürün şartlarının uygulanmasıdır. dışı verilerdir. Daha önce de belirtildiği gibi, buradaki makalelerden biri örnek olay uygulaması. İş mantığı genellikle alana veya verilere yerleştirilir. kullanıcı arayüzü katmanında görünmez.
  • Kullanıcı arayüzü davranış mantığı veya kullanıcı arayüzü mantığı, belirli cihazlarda durum değişikliklerinin nasıl görüntüleneceğini belirtir. ekranda görebilirsiniz. Ekranda gösterilecek doğru metni edinmek de buna örnek olarak gösterilebilir. Android Resources kullanıyorsanız Kullanıcı bir düğmeyi tıkladığında belirli bir ekrana gitme veya ekranda bir kullanıcı mesajı toast veya bir snackbar.

Kullanıcı arayüzü mantığı, özellikle de Context, kullanıcı arayüzünde değil, kullanıcı arayüzünde bulunmalıdır ViewModel'i belirtir. Kullanıcı arayüzü karmaşıklaşıyorsa ve kullanıcı arayüzü için kaygıların ayrıştırılmasını ve test edilebilir olmasını sağlamak adına başka bir sınıfa eyalet sahibi olarak basit bir sınıf oluşturabilir. Kullanıcı arayüzünde oluşturulan basit sınıflar Kullanıcı arayüzünün yaşam döngüsü boyunca uyguladıkları için Android SDK'sı bağımlılıklarını alabilirler. ViewModel nesnelerinin ömrü daha uzundur.

Devlet sahipleri ve devlet kurumlarının kullanıcı arayüzünün derlenmesine yardımcı olmak için Jetpack Compose Durumu rehberini inceleyin.

UDF'yi neden kullanmalısınız?

UDF, Şekil 4'te gösterildiği gibi durum üretim döngüsünü modeller. Aynı zamanda durum değişikliklerinin ortaya çıktığı, dönüştürüldüğü yer, ve bunların nihayetinde tüketildiği yeridir. Bu ayırma, kullanıcı arayüzünün tam olarak ne anlama geliyor? Durum değişikliklerini gözlemleyerek bilgileri görüntüleme, ve bu değişiklikleri ViewModel'e geçirerek kullanıcının amacını aktarmalıdır.

Diğer bir deyişle, UDF şuna izin verir:

  • Veri tutarlılığı. Kullanıcı arayüzü için tek bir doğruluk kaynağı vardır.
  • Test edilebilirlik. Durum kaynağı yalıtılmış ve dolayısıyla test edilebilir kullanıcı arayüzünden bağımsızdır.
  • Sürdürülebilirlik. Durum mutasyonu, iyi tanımlanmış bir kalıp izler. mutasyonlar, hem kullanıcı etkinliklerinin hem de içerdikleri veri kaynaklarının bir sonucudur var.

Kullanıcı arayüzü durumunu kullanıma sunun

Kullanıcı arayüzü durumunuzu tanımlayıp üretimi nasıl yöneteceğinizi belirledikten sonra bir sonraki adım, üretilen durumun kullanıcı arayüzüne sunulmasıdır. Çünkü devlet üretimini yönetmek için UDF'yi kullanıyorsanız, bir akış (başka bir deyişle, eyaletin birden çok versiyonu) olarak nitelendirilir. üretilecektir. Sonuç olarak, kullanıcı arayüzü durumunu LiveData veya StateFlow gibi gözlemlenebilir veri tutucudur. Bunun nedeni, Böylece kullanıcı arayüzü, mevcut durumda yapılan değişikliklere verileri manuel olarak doğrudan ViewModel'den çeker. Ayrıca bu türlerde avantajı, kullanıcı arayüzü durumunun her zaman en son sürümünün önbelleğe alınmasıdır. yapılandırma değişikliklerinden sonra hızlı durum geri yükleme için kullanışlıdır.

Görüntüleme sayısı

class NewsViewModel(...) : ViewModel() {

    val uiState: StateFlow<NewsUiState> = …
}

Oluştur

class NewsViewModel(...) : ViewModel() {

    val uiState: NewsUiState = …
}

Gözlemlenebilir veri sahibi olarak LiveData hakkında tanıtım için bkz. codelab'i tıklayın. Benzer Kotlin akışları hakkında bilgi için Android'de Kotlin akışları başlıklı makaleyi inceleyin.

Kullanıcı arayüzüne sunulan verilerin nispeten basit olduğu durumlarda, genellikle değer sarmalama durum sahibinin ve ilişkili ekranının veya kullanıcı arayüzü öğesinin emisyonu. Ayrıca, kullanıcı arayüzü öğesi daha karmaşık hale geldikçe kullanıcı arayüzü durumunun tanımını, kullanıcı arayüzü öğesini oluşturur.

UiState akışı oluşturmanın yaygın bir yolu, arka değişken değişkeni göstermektir. ViewModel'den sabit bir akış olarak akış olarak gösterir. Örneğin, StateFlow<UiState> olarak MutableStateFlow<UiState>.

Görüntüleme sayısı

class NewsViewModel(...) : ViewModel() {

    private val _uiState = MutableStateFlow(NewsUiState())
    val uiState: StateFlow<NewsUiState> = _uiState.asStateFlow()

    ...

}

Oluştur

class NewsViewModel(...) : ViewModel() {

    var uiState by mutableStateOf(NewsUiState())
        private set

    ...
}

ViewModel daha sonra durumu dahili olarak değiştiren yöntemleri ortaya çıkarabilir, kullanıcı arayüzünün tüketmesi için güncellemeler yayınlayarak. Örneğin, bir şirketin eşzamansız işlemin gerçekleştirilmesi gerekir. koordinat sistemi, viewModelScope ve değişiklik tamamlandıktan sonra durum güncellenebilir.

Görüntüleme sayısı

class NewsViewModel(
    private val repository: NewsRepository,
    ...
) : ViewModel() {

    private val _uiState = MutableStateFlow(NewsUiState())
    val uiState: StateFlow<NewsUiState> = _uiState.asStateFlow()

    private var fetchJob: Job? = null

    fun fetchArticles(category: String) {
        fetchJob?.cancel()
        fetchJob = viewModelScope.launch {
            try {
                val newsItems = repository.newsItemsForCategory(category)
                _uiState.update {
                    it.copy(newsItems = newsItems)
                }
            } catch (ioe: IOException) {
                // Handle the error and notify the UI when appropriate.
                _uiState.update {
                    val messages = getMessagesFromThrowable(ioe)
                    it.copy(userMessages = messages)
                 }
            }
        }
    }
}

Oluştur

class NewsViewModel(
    private val repository: NewsRepository,
    ...
) : ViewModel() {

   var uiState by mutableStateOf(NewsUiState())
        private set

    private var fetchJob: Job? = null

    fun fetchArticles(category: String) {
        fetchJob?.cancel()
        fetchJob = viewModelScope.launch {
            try {
                val newsItems = repository.newsItemsForCategory(category)
                uiState = uiState.copy(newsItems = newsItems)
            } catch (ioe: IOException) {
                // Handle the error and notify the UI when appropriate.
                val messages = getMessagesFromThrowable(ioe)
                uiState = uiState.copy(userMessages = messages)
            }
        }
    }
}

Yukarıdaki örnekte, NewsViewModel sınıfı bir bir arama sonucu ortaya çıkar ve hatasıdır. Bu hata, kullanıcı arayüzünün buna uygun şekilde tepki verebileceği kullanıcı arayüzü durumundadır. Bkz. Hatalar hakkında daha fazla bilgi edinmek için Ekranda hataları göster bölümü ele alacağız.

Göz önünde bulundurulması gereken diğer noktalar

Önceki rehberlere ek olarak, kullanıcı arayüzünü gösterirken aşağıdakileri göz önünde bulundurun eyalet:

  • Bir kullanıcı arayüzü durum nesnesi, birbiriyle ilgili durumları işlemelidir. Böylece tutarsızlığın sayısı azalır ve kodda anlamaktır. Haber öğeleri listesini ve yer işaretleri sayısını görüntülerseniz iki ayrı akışta izlemeye başlarsanız birinin gerçekten diğeri güncellenmedi. Tek bir akış kullandığınızda her iki öğe de her zaman güncel olmasını sağlar. Dahası, bazı iş mantığı süreçleri için aynı zamanda kaynaklar. Örneğin, bir yer işareti düğmesini yalnızca Oturum açmış ve bu kullanıcı bir premium haber hizmetine aboneyse. Aşağıdaki gibi bir kullanıcı arayüzü durum sınıfı tanımlayabilirsiniz:

    data class NewsUiState(
        val isSignedIn: Boolean = false,
        val isPremium: Boolean = false,
        val newsItems: List<NewsItemUiState> = listOf()
    )
    
    val NewsUiState.canBookmarkNews: Boolean get() = isSignedIn && isPremium
    

    Bu beyanda, yer işareti düğmesinin görünürlüğü olmak üzere iki mülktür. İş mantığı daha karmaşık hale geldikçe tüm özelliklerin hemen kullanılabilir olduğu tek bir UiState sınıfı giderek daha önemli hale geliyor.

  • Kullanıcı arayüzü durumları: tek akış mı birden fazla yayın mı? Temel yol gösterici ilke kullanıcı arayüzü durumunu tek bir akışta veya birden fazla akışta gösterme arasında seçim yapmak için akışlar önceki madde işaretidir: öğeler arasındaki ilişki yayınlanır. Tek akışlı karşılaşmanın en büyük avantajı, Veri tutarlılığı: Devlete ait tüketiciler her zaman en güncel bilgilere sahip olur her an erişilebilir. Ancak, bazı durumlarda farklı ViewModel'den gelen durum akışları uygun olabilir:

    • İlişkili olmayan veri türleri: Kullanıcı arayüzünü oluşturmak için gereken bazı durumlar birbirinden tamamen bağımsız olmalıdır. Bu gibi durumlarda, proje bu farklı devletleri gruplandırmak elde edecekleri faydadan ağır basabilir, özellikle de bu durumlardan biri diğerinden daha sık güncellenirse.

    • UiState farkı: UiState nesnesinde ne kadar çok alan olursa akışın, yayın alanlarından biri nedeniyle kaynaklanma olasılığı daha yüksektir güncelleniyor. Çünkü görünümlerin anlaşılması için farklılık mekanizması olmadığından art arda alınan emisyonların farklı veya aynı olup olmadığı, her emisyon görünümün güncellenmesine neden olur. Bu, Flow kullanılarak çözüm için API'ler veya yöntemler distinctUntilChanged() LiveData etiketi gerekli olabilir.

Kullanıcı arayüzü durumunu kullan

Kullanıcı arayüzündeki UiState nesnelerinin akışını kullanmak için terminali kullanın operatörünü kullanabilirsiniz. Örneğin, LiveData için observe() yöntemini, Kotlin akışları için collect() yöntemi veya varyasyonları.

Kullanıcı arayüzünde gözlemlenebilir veri sahiplerini kullanırken aşağıdakileri aldığınızdan emin olun: daha iyi kavrayacaksınız. Bu önemli çünkü kullanıcı arayüzü görünümü, kullanıcı arayüzü belirtir. Bu konu hakkında daha fazla bilgi için bu bloga bakın yayın. LiveData kullanılırken LifecycleOwner, yaşam döngüsünü dolaylı yoldan yönetir emin olun. Akışları kullanırken en iyi yöntem, bunu uygun eş zamanlı kapsam ve repeatOnLifecycle API:

Görüntüleme sayısı

class NewsActivity : AppCompatActivity() {

    private val viewModel: NewsViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect {
                    // Update UI elements
                }
            }
        }
    }
}

Oluştur

@Composable
fun LatestNewsScreen(
    viewModel: NewsViewModel = viewModel()
) {
    // Show UI elements based on the viewModel.uiState
}

Devam eden işlemleri göster

Bir UiState sınıfında yükleme durumlarını göstermenin basit bir yolu, boole alanı:

data class NewsUiState(
    val isFetchingArticles: Boolean = false,
    ...
)

Bu işaretin değeri, Kullanıcı arayüzü.

Görüntüleme sayısı

class NewsActivity : AppCompatActivity() {

    private val viewModel: NewsViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                // Bind the visibility of the progressBar to the state
                // of isFetchingArticles.
                viewModel.uiState
                    .map { it.isFetchingArticles }
                    .distinctUntilChanged()
                    .collect { progressBar.isVisible = it }
            }
        }
    }
}

Oluştur

@Composable
fun LatestNewsScreen(
    modifier: Modifier = Modifier,
    viewModel: NewsViewModel = viewModel()
) {
    Box(modifier.fillMaxSize()) {

        if (viewModel.uiState.isFetchingArticles) {
            CircularProgressIndicator(Modifier.align(Alignment.Center))
        }

        // Add other UI elements. For example, the list.
    }
}

Hataları ekranda göster

Kullanıcı arayüzünde hataların gösterilmesi, devam eden işlemleri göstermeye benzer çünkü boole değerleri, varlıklarını veya değişkenlerini ifade eden eksik. Bununla birlikte, hatalar arasında geri geçiş için bir mesaj da bulunabilir işlemi yeniden denemesini sağlayan ve kullanıcıyla ilişkili bir işlem işlemidir. Dolayısıyla, devam eden bir işlem yüklenirken veya hata durumlarının şunu barındıran veri sınıflarıyla modellenmesi gerekebilir: meta verileri tanımlamayı öğreteceğim.

Örneğin, daha önce bahsettiğimiz bir anahtar kelime ilerleme çubuğu. Bu işlem bir hatayla sonuçlanırsa kullanıcıya ne tür bir işlem gerçekleştirildiğini gösteren bir veya daha fazla yanlış.

data class Message(val id: Long, val message: String)

data class NewsUiState(
    val userMessages: List<Message> = listOf(),
    ...
)

Hata mesajları daha sonra kullanıcıya kullanıcı arayüzü biçiminde sunulabilir snackbar'lar gibi öğeler içerir. Bu, kullanıcı arayüzü etkinliklerinin oluşturulma ve tüketilme şekliyle ilgili olduğu için bkz. Kullanıcı Arayüzü etkinlikler sayfasına bakın.

İleti dizisi ve eşzamanlılık

ViewModel'de gerçekleştirilen tüm çalışmalar main-güvenli olmalıdır; iş parçacığı. Bunun nedeni, veri ve alan katmanlarının ilişkili olduğu ve işi başka bir ileti dizisine taşıyın.

ViewModel uzun süreli işlemler gerçekleştirirse bir arka plan ileti dizisine taşıyabilir. Kotlin eş yordamları eşzamanlı işlemleri yönetmenizi sağlar ve Jetpack Mimari Bileşenleri, yerleşik destek sunuyorlar. Android uygulamalarında eş yordamları kullanma hakkında daha fazla bilgi edinmek için: Android'de Kotlin eş yordamları başlıklı makaleyi inceleyin.

Uygulamada gezinmedeki değişiklikler genellikle etkinliğe benzer emisyonlardan kaynaklanır. Örneğin, bir SignInViewModel sınıfı oturum açtıktan sonra, UiState bir isSignedIn alanı true olarak ayarlandı. Bunun gibi tetikleyiciler yalnızca Kullanıcı arayüzü durumunu kullanma bölümünde ele alınanlar gibi Ancak tüketim uygulamasının, son 30 güne ait Gezinme bileşeni.

Sayfalama

Çağrı kitaplığı: kullanıcı arayüzünde PagingData adlı bir türle tüketilir. Çünkü PagingData zaman içinde değişebilen öğeleri temsil eder ve içerir. Diğer bir deyişle, sabit bir tür değildir ve sabit bir kullanıcı arayüzü durumunda temsil edilmemelidir. Bunun yerine, modeli ViewModel'den bağımsız olarak akış şeklinde gösterilir. Aşağıdakilere ulaşmak için Android Sayfası codelab'ine göz atın: buna örnek verebiliriz.

Animasyonlar

Üst düzey gezinme geçişlerinin akıcı ve sorunsuz olması için animasyonu başlatmadan önce ikinci ekranın veri yüklemesini beklemek istediğinizi varsayalım. Android görünüm çerçevesi parça arasındaki geçişleri geciktirmek için kancalar sağlar şunun olduğu varış noktaları: postponeEnterTransition() ve startPostponedEnterTransition() API'ler. Bu API'ler, ikinci sayfadaki kullanıcı arayüzü öğelerinin ekran (genellikle ağdan getirilen bir görüntü) gösterilmeye hazırdır. o ekrana geçişi canlandırmaya başlamadan önce. Daha fazla bilgi edinmek ve uygulama ayrıntıları için Android Motion örnek bölümüne bakın.

Örnekler

Aşağıdaki Google örnekleri, kullanıcı arayüzü katmanının kullanımını göstermektedir. Uygulamadaki bu rehberliği görmek için bu yöntemleri inceleyin:

ziyaret edin.