Büyük ekranlı tarif defteri

Android, beş yıldızlı büyük ekran uygulamaları için gereken tüm malzemeleri sağlar. Bu tarif defterindeki tarifler, belirli geliştirme sorunlarını çözmek için seçilen malzemeleri seçip birleştirir. Her tarif, büyük ekranda usta bir şef olmanıza yardımcı olacak en iyi uygulamaları, kaliteyle ilgili kod örneklerini ve adım adım açıklamalı talimatları içerir.

Yıldız puanları

Yemek tarifleri, Büyük ekran uygulama kalitesi yönergelerine uyma derecelerine göre yıldız puanına sahiptir.

Beş yıldızlı değerlendirme 1. Katman (Büyük ekran farklılaştırılmış) ölçütlerini karşılıyor
Dört yıldızlı değerlendirme 2. Katman, optimize edilmiş büyük ekran ölçütlerini karşılıyor
Üç yıldızlı değerlendirme 3. Katman, "Büyük ekran hazır" ölçütlerini karşılıyor
İki yıldız puanı Bazı büyük ekran özellikleri sunar, ancak büyük ekran uygulaması kalite yönergelerinin gerisinde kalmaktadır
Bir yıldızlı değerlendirme Belirli bir kullanım alanının ihtiyaçlarını karşılıyor ancak büyük ekranları düzgün desteklemiyor.

Chromebook kamera desteği

Üç yıldızlı değerlendirme

Chromebook kullanıcılarının Google Play'de dikkatlerini çekin.

Kamera uygulamanız yalnızca temel kamera özellikleriyle çalışabiliyorsa uygulama mağazalarının, sırf ileri teknoloji telefonlarda bulunan gelişmiş kamera özelliklerini yanlışlıkla belirtmiş olmanız nedeniyle Chromebook kullanıcılarının uygulamayı yüklemesini engellemesine izin vermeyin.

Chromebook'larda video konferans, anlık görüntü ve diğer uygulamalar için iyi çalışan yerleşik bir ön (kullanıcıya yönelik) kamera vardır. Ancak tüm Chromebook'larda arka (dünyaya bakan) kamera bulunmaz ve Chromebook'lardaki kullanıcılara yönelik çoğu kamera otomatik odaklama veya flaşı desteklemez.

En iyi uygulamalar

Çok yönlü kamera uygulamaları, kamera yapılandırması ne olursa olsun tüm cihazları destekler. Ön kameralar, arka kameralar, USB ile bağlanan harici kameralar olan cihazlar.

Uygulama mağazalarının uygulamanızı en fazla sayıda cihazda kullanıma sunmasını sağlamak için uygulamanızın kullandığı tüm kamera özelliklerini daima beyan edin ve özelliklerin gerekli olup olmadığını açıkça belirtin.

Malzemeler

  • CAMERA izni: Uygulamanızın, bir cihazdaki kameralara erişmesine izin verir
  • <uses-feature> manifest öğesi: Uygulama mağazalarını, uygulamanız tarafından kullanılan özellikler hakkında bilgilendirir
  • required özelliği: Uygulamanızın belirtilen bir özellik olmadan çalışıp çalışamayacağını uygulama mağazalarına belirtir

Adımlar

Özet

CAMERA iznini beyan edin. Temel kamera desteği sağlayan kamera özelliklerini beyan edin. Her bir özelliğin gerekli olup olmadığını belirtin.

1. CAMERA iznini beyan edin

Uygulama manifestine aşağıdaki izni ekleyin:

<uses-permission android:name="android.permission.CAMERA" />
2. Temel kamera özelliklerini beyan etme

Uygulama manifestine aşağıdaki özellikleri ekleyin:

<uses-feature android:name="android.hardware.camera.any" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
3. Her bir özelliğin gerekli olup olmadığını belirtin

Herhangi bir yerleşik veya harici kamerası olan ya da hiç kamerası olmayan cihazların uygulamanıza erişebilmesini sağlamak için android.hardware.camera.any özelliği için android:required="false" ayarlayın.

Diğer özelliklerle ilgili olarak arka kamerası, otomatik odaklama veya flaş olmayan Chromebook gibi cihazların uygulama mağazalarında uygulamanıza erişebilmesi için android:required="false" ayarını yapın.

Sonuçlar

Chromebook kullanıcıları, uygulamanızı Google Play'den ve diğer uygulama mağazalarından indirip yükleyebilirler. Telefonlar gibi tam özellikli kamera desteği sunan cihazların kamera işlevleri ise kısıtlanmaz.

Uygulamanızın desteklediği kamera özelliklerini açık bir şekilde ayarlayıp uygulamanızın gerektirdiği özellikleri belirterek uygulamanızı mümkün olduğunca fazla cihazın kullanımına sunmuş olursunuz.

Ek kaynaklar

Daha fazla bilgi için <uses-feature> dokümanlarındaki Kamera donanımı özellikleri bölümüne bakın.

Uygulama yönü telefonlarda kısıtlanıyor ancak büyük ekranlı cihazlarda geçerli değil

İki yıldız puanı

Uygulamanız dikey yönlü telefonlarda sorunsuz çalıştığından uygulamayı yalnızca dikey olarak sınırlandırdınız. Ancak yatay yönde büyük ekranlarda daha fazlasını yapma fırsatına sahipsiniz.

Bunu her iki durumda da nasıl yapabilirsiniz? Küçük ekranlarda uygulamayı dikey yönde sınırlayıp büyük ekranda yatay uygulamayı nasıl etkinleştirebilirsiniz?

En iyi uygulamalar

En iyi uygulamalar, cihaz yönü gibi kullanıcı tercihlerine saygı gösterir.

Büyük ekran uygulama kalitesi yönergelerinde, uygulamaların dikey ve yatay yönler, çoklu pencere modu ve katlanabilir cihazların katlanmış ve açık durumları dahil olmak üzere tüm cihaz yapılandırmalarını desteklemesi önerilir. Uygulamalar, farklı yapılandırmalar için düzenleri ve kullanıcı arayüzlerini optimize etmelidir. Uygulamalar, yapılandırma değişiklikleri sırasında durumu kaydedip geri yüklemelidir.

Bu yemek tarifi, geçici bir çözümdür ve büyük ekran desteğine sahiptir. Uygulamanızı tüm cihaz yapılandırmaları için tam destek sağlayacak şekilde iyileştirene kadar bu tarifi kullanın.

Malzemeler

  • screenOrientation: Uygulamanızın cihaz yönü değişikliklerine nasıl tepki vereceğini belirtmenizi sağlayan uygulama manifesti ayarı
  • Jetpack WindowManager: Uygulama penceresinin boyutunu ve en boy oranını belirlemenizi sağlayan kitaplıklar grubu; API düzeyi 14'e kadar geriye dönük uyumludur
  • Activity#setRequestedOrientation(): Çalışma zamanında uygulamanın yönünü değiştirmek için kullanabileceğiniz yöntem

Adımlar

Özet

Uygulamanın, uygulama manifest dosyasında varsayılan olarak yön değişikliklerini işlemesini etkinleştirin. Çalışma zamanında uygulama pencere boyutunu belirleyin. Uygulama penceresi küçükse manifest yönü ayarını geçersiz kılarak uygulamanın yönünü kısıtlayın.

1. Uygulama manifest dosyasında yön ayarını belirtin

Uygulama manifest'inin screenOrientation öğesini tanımlamaktan kaçınabilir (bu durumda yön varsayılan olarak unspecified olur) veya ekran yönünü fullUser olarak ayarlayabilirsiniz. Kullanıcı, sensöre dayalı döndürmeyi kilitlemediyse uygulamanız tüm cihaz yönlerini destekler.

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

unspecified ve fullUser kullanımı arasındaki fark çok küçük olmasa da önemlidir. screenOrientation değeri beyan etmezseniz yönü sistem seçer. Sistemin yönü tanımlamak için kullandığı politika da cihazdan cihaza değişebilir. Diğer yandan, fullUser belirtilmesi, kullanıcının cihaz için tanımladığı davranışa daha yakındır: Kullanıcı sensöre dayalı döndürmeyi kilitlediyse uygulama, kullanıcı tercihini uygular. Aksi takdirde, sistem olası dört ekran yönünden herhangi birine (dikey, yatay, ters dikey veya ters yatay) izin verir. android:screenOrientation başlıklı makaleyi inceleyin.

2. Ekran boyutunu belirleme

Manifest, kullanıcıların izin verdiği tüm yönleri destekleyecek şekilde ayarlandığında, ekran boyutuna göre uygulama yönünü programatik olarak belirtebilirsiniz.

Jetpack WindowManager kitaplıklarını modülün build.gradle veya build.gradle.kts dosyasına ekleyin:

Kotlin

implementation("androidx.window:window:version")
implementation("androidx.window:window-core:version")

Eski

implementation 'androidx.window:window:version'
implementation 'androidx.window:window-core:version'

Cihazın ekran boyutunu WindowMetrics nesnesi olarak elde etmek için Jetpack WindowManager WindowMetricsCalculator#computeMaximumWindowMetrics() yöntemini kullanın. Yönün ne zaman kısıtlanacağına karar vermek için pencere boyutu sınıflarıyla karşılaştırılabilir.

Windows boyut sınıfları, küçük ve büyük ekranlar arasındaki ayrılma noktalarını sağlar.

Ekran boyutunu belirlemek için WindowWidthSizeClass#COMPACT ve WindowHeightSizeClass#COMPACT ayrılma noktalarını kullanın:

Kotlin

/** Determines whether the device has a compact screen. **/
fun compactScreen() : Boolean {
    val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
    val width = metrics.bounds.width()
    val height = metrics.bounds.height()
    val density = resources.displayMetrics.density
    val windowSizeClass = WindowSizeClass.compute(width/density, height/density)

    return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT ||
        windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT
}

Java

/** Determines whether the device has a compact screen. **/
private boolean compactScreen() {
    WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this);
    int width = metrics.getBounds().width();
    int height = metrics.getBounds().height();
    float density = getResources().getDisplayMetrics().density;
    WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density);
    return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT ||
                windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT;
}
    Not:
  • Yukarıdaki örnekler, bir etkinliğin yöntemleri olarak uygulanmıştır; bu nedenle, computeMaximumWindowMetrics() bağımsız değişkeninde etkinliğin this referansı kaldırılmıştır.
  • Uygulama, ekran yönü ayarını yok sayan çoklu pencere modunda başlatılabileceği için computeCurrentWindowMetrics() yerine computeMaximumWindowMetrics() yöntemi kullanılır. Uygulama penceresi cihaz ekranının tamamını kaplamadığı sürece uygulama pencere boyutunu belirlemenin ve yön ayarını geçersiz kılmanın bir anlamı yoktur.

computeMaximumWindowMetrics() yöntemini uygulamanızda kullanılabilmesini sağlamak için bağımlılıkları bildirmeyle ilgili talimatlar için WindowManager bölümüne bakın.

3. Uygulama manifesti ayarını geçersiz kıl

Cihazın küçük ekran boyutuna sahip olduğunu belirledikten sonra Activity#setRequestedOrientation() öğesini çağırarak manifestin screenOrientation ayarını geçersiz kılabilirsiniz:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestedOrientation = if (compactScreen())
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    val container: ViewGroup = binding.container

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(object : View(this) {
        override fun onConfigurationChanged(newConfig: Configuration?) {
            super.onConfigurationChanged(newConfig)
            requestedOrientation = if (compactScreen())
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
                ActivityInfo.SCREEN_ORIENTATION_FULL_USER
        }
    })
}

Java

@Override
protected void onCreate(Bundle savedInstance) {
    super.onCreate(savedInstanceState);
    if (compactScreen()) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
    }
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    ViewGroup container = binding.container;

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(new View(this) {
        @Override
        protected void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (compactScreen()) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER);
            }
        }
    });
}

Mantığı onCreate() ve View.onConfigurationChanged() yöntemlerine ekleyerek, maksimum pencere metriklerini elde edebilir ve etkinlik yeniden boyutlandırıldığında veya ekranlar arasında taşındığında (ör. cihazın döndürülmesinden sonra ya da katlanabilir cihaz katlanabilir veya açılmışsa) yön ayarını geçersiz kılabilirsiniz. Yapılandırma değişikliklerinin ne zaman gerçekleştiği ve bunların ne zaman etkinlik yeniden oluşturulmasına neden olduğu hakkında daha fazla bilgi için Yapılandırma değişikliklerini işleme başlıklı makaleyi inceleyin.

Sonuçlar

Uygulamanız artık küçük ekranlarda cihazın yönünü ne olursa olsun dikey yönde kalmalıdır. Uygulama, büyük ekranlarda yatay ve dikey yönleri desteklemelidir.

Ek kaynaklar

Uygulamanızı her zaman tüm cihaz yapılandırmalarını destekleyecek şekilde yükseltmeyle ilgili yardım için aşağıdaki konulara bakın:

Harici klavyede Boşluk Çubuğuyla medya oynatmayı duraklatma ve devam ettirme

Dört yıldızlı değerlendirme

Büyük ekran optimizasyonu, videoların ve diğer medyaların oynatılmasını duraklatmak veya devam ettirmek için Boşluk tuşuna basılmasına tepki vermek gibi harici klavye girişlerini yönetebilmeyi de içerir. Bu özellikle, genellikle harici klavyelere bağlanan tabletler ve genellikle harici klavyelerle birlikte gelen ancak tablet modunda kullanılabilen Chromebook'lar için yararlıdır.

Medya, pencerenin tek öğesi olduğunda (tam ekran video oynatma gibi), tuşa basma etkinliklerine etkinlik düzeyinde veya Jetpack Compose'da ekran düzeyinde yanıt verin.

En iyi uygulamalar

Uygulamanız bir medya dosyası oynattığında, kullanıcılar fiziksel klavyede Boşluk tuşuna basarak oynatmayı duraklatıp devam ettirebilmelidir.

Malzemeler

Oluşturma

  • onPreviewKeyEvent: Bir bileşenin (veya alt birimlerinden birine) odaklanıldığında donanımla ilgili önemli etkinliklere müdahale etmesini sağlayan Modifier.
  • onKeyEvent: onPreviewKeyEvent özelliğine benzer şekilde, bu Modifier bir bileşenin (veya alt birimlerinden birine) odaklanıldığında donanımla ilgili önemli etkinliklere müdahale etmesini sağlar.

Görüntüleme sayısı

  • onKeyUp(): Bir anahtar serbest bırakıldığında ve bir etkinlikteki görünüm tarafından işlenmediğinde çağrılır.

Adımlar

Özet

Jetpack Compose'u temel alan görünüm tabanlı uygulamalar ve uygulamalar klavye tuşlarına benzer şekilde basın. Uygulama tuşa basma etkinliklerini dinlemeli, etkinlikleri filtrelemeli ve Boşluk tuşuna basma gibi seçilen tuşlara yanıt vermelidir.

1. Klavye etkinliklerini dinleme

Görüntüleme sayısı

Uygulamanızdaki bir etkinlikte, onKeyUp() yöntemini geçersiz kılın:

Kotlin

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
    ...
}

Java

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    ...
}

Yöntem, basılan bir tuş her serbest bırakıldığında çağrılır. Dolayısıyla, her tuş vuruşunda tam olarak bir kez etkinleşir.

Oluşturma

Jetpack Compose'da tuş vuruşunu yöneten onPreviewKeyEvent veya onKeyEvent değiştiricisinden yararlanabilirsiniz:

Column(modifier = Modifier.onPreviewKeyEvent { event ->
    if (event.type == KeyEventType.KeyUp) {
        ...
    }
    ...
})

veya

Column(modifier = Modifier.onKeyEvent { event ->
    if (event.type == KeyEventType.KeyUp) {
        ...
    }
    ...
})

2. Filtre Boşluk tuşuna basıldığında

onKeyUp() yönteminde veya Oluştur onPreviewKeyEvent ve onKeyEvent değiştirici yöntemlerinde, medya bileşeninize doğru etkinliği göndermek için KeyEvent.KEYCODE_SPACE filtresini uygulayın:

Görüntüleme sayısı

Kotlin

if (keyCode == KeyEvent.KEYCODE_SPACE) {
    togglePlayback()
    return true
}
return false

Java

if (keyCode == KeyEvent.KEYCODE_SPACE) {
    togglePlayback();
    return true;
}
return false;

Oluşturma

Column(modifier = Modifier.onPreviewKeyEvent { event ->
    if (event.type == KeyEventType.KeyUp && event.key == Key.Spacebar) {
        ...
    }
    ...
})

veya

Column(modifier = Modifier.onKeyEvent { event ->
    if (event.type == KeyEventType.KeyUp && event.key == Key.Spacebar) {
        ...
    }
    ...
})

Sonuçlar

Uygulamanız artık bir videoyu veya başka bir medyayı duraklatmak ve devam ettirmek için Boşluk tuşuna basıldığında yanıt verebilir.

Ek kaynaklar

Klavye etkinlikleri ve bunların nasıl yönetileceği hakkında daha fazla bilgi edinmek için Klavye girişini işleme bölümüne bakın.

Ekran kalemi avuç içi reddi

Beş yıldızlı değerlendirme

Ekran kalemi, büyük ekranlarda son derece üretken ve yaratıcı bir araç olabilir. Ancak kullanıcılar ekran kalemi kullanarak çizim yaparken, yazarken veya uygulamayla etkileşimde bulunurken bazen avuçlarıyla ekrana dokunur. Dokunma etkinliği, sistem tarafından yanlışlıkla avuç içi dokunma olarak algılanıp etkinliği kapatmadan önce uygulamanıza bildirilebilir.

En iyi uygulamalar

Uygulamanız, fazladan dokunma etkinliklerini tanımlamalı ve bunları yoksaymalıdır. Android, bir MotionEvent nesnesi göndererek avuç içi dokunuşunu iptal eder. Avuç içi dokunuşu nedeniyle yapılan hareketin reddedilip reddedilmeyeceğini belirlemek için nesnede ACTION_CANCEL veya ACTION_POINTER_UP ve FLAG_CANCELED olup olmadığını kontrol edin.

Malzemeler

  • MotionEvent: Dokunma ve hareket etkinliklerini temsil eder. Bir olayın göz ardı edilmesi gerekip gerekmediğini belirlemek için gerekli bilgileri içerir.
  • OnTouchListener#onTouch(): MotionEvent nesne alır.
  • MotionEvent#getActionMasked(): Bir hareket etkinliğiyle ilişkilendirilmiş işlemi döndürür.
  • ACTION_CANCEL: Hareketin geri alınması gerektiğini belirten MotionEvent sabit değer.
  • ACTION_POINTER_UP: İlk işaretçinin dışındaki bir işaretçinin yukarı çıktığını (yani cihaz ekranıyla temastan vazgeçtiğini) gösteren MotionEvent sabit değeri.
  • FLAG_CANCELED: Yukarı giden işaretçinin yanlışlıkla dokunma etkinliğine neden olduğunu belirten MotionEvent sabit değeri. Android 13 (API düzeyi 33) ve sonraki sürümlerde ACTION_POINTER_UP ve ACTION_CANCEL etkinliklerine eklendi.

Adımlar

Özet

Uygulamanıza gönderilen MotionEvent nesneyi inceleyin. Etkinlik özelliklerini belirlemek için MotionEvent API'lerini kullanın:

  • Tek işaretçi etkinlikleri: ACTION_CANCEL olup olmadığını kontrol edin. Android 13 ve sonraki sürümlerde FLAG_CANCELED olup olmadığını da kontrol edin.
  • Birden çok işaretçili etkinlikler: Android 13 ve sonraki sürümlerde ACTION_POINTER_UP ve FLAG_CANCELED özelliklerini kontrol edin.

ACTION_CANCEL ve ACTION_POINTER_UP/FLAG_CANCELED etkinliklerine yanıt verin.

1. Hareket etkinliği nesnelerini edinme

Uygulamanıza OnTouchListener ekleyin:

Kotlin

val myView = findViewById<View>(R.id.myView).apply {
    setOnTouchListener { view, event ->
        // Process motion event.
    }
}

Java

View myView = findViewById(R.id.myView);
myView.setOnTouchListener( (view, event) -> {
    // Process motion event.
});
2. Etkinlik işlemini ve işaretleri belirleme

Tüm API düzeylerinde tek işaretçili bir etkinliği gösteren ACTION_CANCEL olup olmadığını kontrol edin. Android 13 ve sonraki sürümlerde FLAG_CANCELED. için ACTION_POINTER_UP uygulamasını kontrol edin

Kotlin

val myView = findViewById<View>(R.id.myView).apply {
    setOnTouchListener { view, event ->
        when (event.actionMasked) {
            MotionEvent.ACTION_CANCEL -> {
                //Process canceled single-pointer motion event for all SDK versions.
            }
            MotionEvent.ACTION_POINTER_UP -> {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                   (event.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) {
                    //Process canceled multi-pointer motion event for Android 13 and higher.
                }
            }
        }
        true
    }
}

Java

View myView = findViewById(R.id.myView);
myView.setOnTouchListener( (view, event) -> {
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_CANCEL:
            // Process canceled single-pointer motion event for all SDK versions.
        case MotionEvent.ACTION_UP:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
               (event.getFlags() & MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) {
                //Process canceled multi-pointer motion event for Android 13 and higher.
            }
    }
    return true;
});
3. Hareketi geri al

Avuç içi dokunuşunu belirledikten sonra, hareketin ekrandaki etkilerini geri alabilirsiniz.

Avuç içi dokunma gibi istenmeyen girişlerin geri alınabilmesi için uygulamanızın kullanıcı işlemlerinin geçmişini saklaması gerekir. Örnek için Android uygulamasında ekran kalemi desteğini geliştirme adlı codelab'de yer alan Temel bir çizim uygulaması uygulama bölümüne bakın.

Sonuçlar

Uygulamanız artık Android 13 ve sonraki sürümlerdeki API düzeylerinde, tüm API düzeylerinde tek noktalı etkinlikler için avuç içi dokunmalarını tanımlayıp reddedebilir.

Ek kaynaklar

Daha fazla bilgi için aşağıdaki konulara bakın:

WebView durum yönetimi

Üç yıldızlı değerlendirme

WebView, durum yönetimi için gelişmiş bir sistem sunan yaygın olarak kullanılan bir bileşendir. WebView, yapılandırma değişiklikleri genelinde durumunu ve kaydırma konumunu korumalıdır. WebView, kullanıcı cihazı döndürdüğünde veya katlanabilir telefonu açtığında kaydırma konumunu kaybedebilir. Bu durum, kullanıcıyı WebView öğesinin üst kısmından önceki kaydırma konumuna tekrar kaydırmaya zorlar.

En iyi uygulamalar

Bir WebView öğesinin yeniden oluşturulma sayısını en aza indirin. WebView, durumunu yönetme konusunda başarılıdır. Mümkün olduğunca çok sayıda yapılandırma değişikliğini yöneterek bu kaliteden yararlanabilirsiniz. Uygulamanız, Activity yeniden oluşturma (sistemin yapılandırma değişikliklerini işleme yöntemi) WebView öğesini de yeniden oluşturduğu için yapılandırma değişikliklerini işlemelidir. Bu durum, WebView öğesinin durumunu kaybetmesine neden olur.

Malzemeler

  • android:configChanges: Manifest <activity> öğesinin özelliği. Etkinlik tarafından işlenen yapılandırma değişikliklerini listeler.
  • View#invalidate(): Bir görünümün yeniden çizilmesine neden olan yöntem. WebView tarafından devralındı.

Adımlar

Özet

WebView durumunu kaydetmek için Activity yeniden oluşturma işlemini mümkün olduğunca kullanmaktan kaçının ve ardından WebView öğesinin, durumunu korurken yeniden boyutlandırması için geçersiz kılmasına izin verin.

1. Uygulamanızın AndroidManifest.xml dosyasına yapılandırma değişikliklerini ekleyin

Uygulamanız tarafından (sistem tarafından değil) işlenen yapılandırma değişikliklerini belirterek etkinliği yeniden oluşturma işlemini önleyin:

<activity
  android:name=".MyActivity"
  android:configChanges="screenLayout|orientation|screenSize
      |keyboard|keyboardHidden|smallestScreenSize" />

2. Uygulamanız yapılandırma değişikliği aldığında WebView özelliğini geçersiz kılın

Kotlin

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    webView.invalidate()
}

Java

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    webview.invalidate();
}

Jetpack Compose'un Composable öğelerini doğru şekilde yeniden boyutlandırmak için herhangi bir şeyi geçersiz kılması gerekmediğinden bu adım yalnızca görünüm sistemi için geçerlidir. Ancak Compose doğru yönetilmezse genellikle bir WebView oluşturur. Compose uygulamalarınızda WebView durumunu kaydedip geri yüklemek için Accompanist WebView sarmalayıcısını kullanın.

Sonuçlar

Uygulamanızın WebView bileşenleri artık yeniden boyutlandırmadan yön değişikliğine, katlama ve açma işlemine kadar çeşitli yapılandırma değişikliklerinde durumlarını ve kaydırma konumlarını koruyor.

Ek kaynaklar

Yapılandırma değişiklikleri ve bunların nasıl yönetileceği hakkında daha fazla bilgi edinmek için Yapılandırma değişikliklerini işleme başlıklı makaleyi inceleyin.

RecyclerView durum yönetimi

Üç yıldızlı değerlendirme

RecyclerView, minimum grafik kaynağı kullanarak büyük miktarda veri görüntüleyebilir. RecyclerView öğe listesinde gezinirken RecyclerView, ekranda kaydırılan yeni öğeler oluşturmak için ekranın dışına kaydırılan View öğeleri yeniden kullanır. Ancak, cihaz döndürme gibi yapılandırma değişiklikleri, bir RecyclerView öğesinin durumunu sıfırlayabilir ve kullanıcıları RecyclerView öğeden oluşan listede tekrar önceki konumlarına kaydırmaya zorlayabilir.

En iyi uygulamalar

RecyclerView, tüm yapılandırma değişiklikleri sırasında durumunu (özellikle kaydırma konumunu) ve liste öğelerinin durumunu korumalıdır.

Malzemeler

Adımlar

Özet

RecyclerView kaydırma konumunu kaydetmek için RecyclerView.Adapter durum geri yükleme politikasını ayarlayın. RecyclerView liste öğesinin durumunu kaydet. Liste öğelerinin durumunu RecyclerView bağdaştırıcısına ekleyin ve liste öğelerinin bir ViewHolder'a bağlı olduklarında durumunu geri yükleyin.

1. Adapter durumu geri yükleme politikasını etkinleştir

Yapılandırma değişikliklerinde RecyclerView öğesinin kaydırma konumunun korunması için RecyclerView bağdaştırıcısının durum geri yükleme politikasını etkinleştirin. Bağdaştırıcı oluşturucuya politika spesifikasyonunu ekleyin:

Kotlin

class MyAdapter() : RecyclerView.Adapter() {
    init {
        stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
    }
    ...
}

Java

class MyAdapter extends RecyclerView.Adapter {

    public Adapter() {
        setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY);
    }
    ...
}

2. Durum bilgili liste öğelerinin durumunu kaydet

Karmaşık RecyclerView liste öğelerinin (ör. EditText öğeleri içeren öğeler) durumunu kaydedin. Örneğin, bir EditText durumunu kaydetmek için, metin değişikliklerini yakalamak amacıyla onClick işleyicisine benzer bir geri çağırma ekleyin. Geri çağırma özelliğinde, hangi verilerin kaydedileceğini tanımlayın:

Kotlin

input.addTextChangedListener(
    afterTextChanged = { text ->
        text?.let {
            // Save state here.
        }
    }
)

Java

input.addTextChangedListener(new TextWatcher() {

    ...

    @Override
    public void afterTextChanged(Editable s) {
        // Save state here.
    }
});

Geri çağırmayı Activity veya Fragment üzerinden beyan edin. Durumu depolamak için ViewModel kullanın.

3. Liste öğesi durumunu Adapter özelliğine ekle

Liste öğelerinin durumunu RecyclerView.Adapter cihazınıza ekleyin. Activity veya Fragment ana makineniz oluşturulduğunda öğe durumunu bağdaştırıcı oluşturucuya iletin:

Kotlin

val adapter = MyAdapter(items, viewModel.retrieveState())

Java

MyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());

4. Bağdaştırıcının ViewHolder uygulamasında liste öğesi durumunu kurtar

RecyclerView.Adapter içinde, bir öğeye ViewHolder bağladığınızda öğenin durumunu geri yükleyin:

Kotlin

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    ...
    val item = items[position]
    val state = states.firstOrNull { it.item == item }

    if (state != null) {
        holder.restore(state)
    }
}

Java

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    ...
    Item item = items[position];
    Arrays.stream(states).filter(state -> state.item == item)
        .findFirst()
        .ifPresent(state -> holder.restore(state));
}

Sonuçlar

RecyclerView cihazınız artık kaydırma konumunu ve RecyclerView listesindeki her öğenin durumunu geri yükleyebilir.

Ek kaynaklar

Çıkarılabilir klavye yönetimi

Üç yıldızlı değerlendirme

Çıkarılabilir klavye desteği, büyük ekranlı cihazlarda kullanıcı verimliliğini en üst düzeye çıkarmaya yardımcı olur. Android, bir klavyeye her bağlandığında veya cihazdan çıkarıldığında bir yapılandırma değişikliği tetikler. Bu durum, kullanıcı arayüzü durumu kaybına neden olabilir. Uygulamanız, durumunu kaydedip geri yükleyerek sistemin etkinlik yeniden oluşturmayı işlemesine izin verebilir veya klavye yapılandırma değişiklikleri için etkinlik yeniden oluşturmayı kısıtlayabilir. Her durumda, klavyeyle ilgili tüm veriler bir Configuration nesnesinde depolanır. Yapılandırma nesnesinin keyboard ve keyboardHidden alanları, klavye türü ve kullanılabilirliği hakkında bilgi içerir.

En iyi uygulamalar

Büyük ekranlar için optimize edilmiş uygulamalar yazılım ve donanım klavyelerinden ekran kalemine, fareye, dokunmatik yüzeye ve diğer çevre birimi cihazlarına kadar her türlü giriş cihazını destekler.

Harici klavye desteğinde yapılandırma değişikliklerini içerir. Bu değişiklikleri iki şekilde yönetebilirsiniz:

  1. Sistemin şu anda çalışan etkinliği yeniden oluşturmasına izin verin, uygulamanızın durumunu siz yönetin.
  2. Yapılandırma değişikliğini kendiniz yönetin (etkinlik yeniden oluşturulmaz):
    • Klavyeyle ilgili tüm yapılandırma değerlerini bildir
    • Yapılandırma değişiklik işleyicisi oluşturma

Genellikle metin girişi ve diğer girişler için kullanıcı arayüzünün hassas bir şekilde kontrol edilmesini gerektiren üretkenlik uygulamaları, yapılandırma değişikliklerini yönetmek için "kendin yap" yaklaşımından yararlanabilir.

Özel durumlarda, bir donanım klavyesi takılıyken veya çıkarılırken uygulamanızın düzenini değiştirmek isteyebilirsiniz (örneğin, araçlara veya düzenleme pencereleri için daha fazla yer açmak).

Yapılandırma değişikliklerini dinlemenin tek güvenilir yolu bir görünümün onConfigurationChanged() yöntemini geçersiz kılmak olduğundan uygulama etkinliğinize yeni bir View örneği ekleyebilir ve klavyenin takılmasından veya çıkarılmasından kaynaklanan yapılandırma değişikliklerine görünümün onConfigurationChanged() işleyicisinde yanıt verebilirsiniz.

Malzemeler

  • android:configChanges: Uygulama manifesti <activity> öğesinin özelliği. Uygulamanın yönettiği yapılandırma değişiklikleri hakkında sistemi bilgilendirir.
  • View#onConfigurationChanged(): Yeni bir uygulama yapılandırmasının yayılmasına tepki veren yöntem.

Adımlar

Özet

configChanges özelliğini tanımlayın ve klavyeyle ilgili değerleri ekleyin. Etkinliğin görünüm hiyerarşisine View ekleyin ve yapılandırma değişikliklerini dinleyin.

1. configChanges özelliğini bildir

Zaten yönetilen yapılandırma değişiklikleri listesine keyboard|keyboardHidden değerlerini ekleyerek uygulama manifestindeki <activity> öğesini güncelleyin:

<activity
      …
      android:configChanges="...|keyboard|keyboardHidden">

2. Görünüm hiyerarşisine boş bir görünüm ekleyin

Yeni bir görünüm tanımlayın ve işleyici kodunuzu görünümün onConfigurationChanged() yöntemine ekleyin:

Kotlin

val v = object : View(this) {
  override fun onConfigurationChanged(newConfig: Configuration?) {
    super.onConfigurationChanged(newConfig)
    // Handler code here.
  }
}

Java

View v = new View(this) {
    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Handler code here.
    }
};

Sonuçlar

Uygulamanız artık o anda çalışan etkinliği yeniden oluşturmadan, takılan veya çıkarılan harici klavyeye yanıt verir.

Ek kaynaklar

Klavye eki veya ayırma gibi yapılandırma değişiklikleri sırasında uygulamanızın kullanıcı arayüzü durumunu nasıl kaydedeceğinizi öğrenmek için Kullanıcı arayüzü durumlarını kaydetme bölümüne bakın.