Uygulama temeli

Jetpack Compose ile giriş etkileşimlerini dokunmatik ekranın ötesine ölçeklendirme

Hoparlörler

  • Alex Vanyo

    Yazılım Mühendisi

  • Jeremy Walker

    Compose Yazılım Mühendisi

Hakkında

Konuşma hakkında

Yeni form faktörleri dokunmatik ekranın ötesine geçerken Compose'un giriş sistemi de bu zorluğun üstesinden gelecek şekilde gelişti. Katmanlı mimarisi, gelişmiş dokunmatik yüzey hareketlerinden yeni donanım girişlerine kadar her şeyi sorunsuz bir şekilde desteklemenin temelini oluşturur.

Net mimari dökümler ve uygulamalı kod örnekleri aracılığıyla, bir giriş etkinliğinin yaşam döngüsünü işletim sistemi platform katmanından Compose hareket algılayıcılarına ve kullanıcı arayüzü bileşenlerine kadar takip edin. Etkinlikleri tüm yığın boyunca nasıl izleyeceğinizi, yeni giriş türleri için temel mimari kalıpları nasıl uygulayacağınızı ve kendi uygulamalarınızdaki karmaşık hareket etkileşimlerinde nasıl güvenle hata ayıklayacağınızı öğreneceksiniz.

Özet

  • Jetpack Compose, gelen Android işaretçi etkinliklerini altı aşamalı bir ardışık düzen aracılığıyla işler. Bu ardışık düzen, bir isabet yolu ağacı tutar ve kullanıcı arayüzü düğümleri arasında üç geçişte etkinlikleri gönderir.
  • Compose'daki dokunmatik yüzey girişleri artık dokunma yerine fare etkinlikleriyle eşlenir. Compose, platformun sahte parmak etkinliklerini özel kaydırma ve ölçeklendirme işaretçi etkinliklerine de dönüştürür.
  • Akıllı gözlük dokunmatik yüzeyleri, ekrana dokunarak koordinat belirleme yerine dolaylı giriş türleri sunar. Yatay kaydırma hareketlerini dikey sonraki veya önceki gezinme hareketleriyle eşlemek için birincil yönlü hareket ekseni kullanırlar.
  • Test desteği, performTrackpadInput gibi yeni yöntemlerle dokunmanın ötesine geçti. Bu API'ler, uygulamaların dokunmatik olmayan cihazları doğru şekilde işlediğini doğrulamak için tanıdık test yüzeyleri sağlar.

Gemini Notebook

Konular

  • jetpack-compose
  • pointer-input
  • dokunmatik yüzeyler
  • hareketler
  • akıllı gözlük
  • erişilebilirlik

Transkript

Giriş ve giriş felsefesi

  • Herkese merhaba.

  • Android Developer Summit'te iyi vakit geçirdiğinizi umuyoruz. Konuşmamıza katıldığınız için teşekkür ederiz.

  • Ben Alex Vanyo, Compose ekibinde yazılım mühendisiyim. Compose ekibinden bir diğer yazılım mühendisi Jeremy de bana eşlik ediyor.

  • İkimiz de Jetpack Compose'un giriş sistemini geliştirmek için çalışıyoruz. Bugün, dokunmatik olmayan girişleri kullanıma hazır bir şekilde desteklemeyi kolaylaştırmak için bu sistemleri dokunmatik ekranın ötesine nasıl ölçeklendirdiğimizden bahsedeceğiz.

  • Giriş, genel olarak kullanıcının uygulamanızla etkileşim kurma şeklini ifade eder.

  • Mobil uygulama dendiğinde akla ilk gelen şey dokunmatik ekranlar olsa da tek giriş türü kesinlikle bu değildir.

  • Diğer giriş türleri arasında fiziksel klavyeler, fareler, dokunmatik yüzeyler, ekran kalemleri, kumandalar ve döner cihazlar yer alır.

  • Ayrıca akıllı gözlüklerdeki dokunmatik yüzeyler, XR'da göz ve el takibi, Wear'da parmak ve bilek hareketleri gibi yeni giriş türleri de görüyoruz.

  • Daha da genel bir yaklaşım benimsemek isterseniz başka giriş türleri de vardır: metin düzenleme için yazılım IME'leri, mikrofonlar, kameralar ve diğer cihaz sensörleri gibi.

  • Uygulamalarınızın çok çeşitli giriş türleriyle kullanılacağını göz önünde bulundurmanız gerekir.

  • Bunun bir nedeni, uygulamaların çalıştığı cihaz çeşitliliğinin ve bu cihazların uyarlanabilirliğinin sürekli artmasıdır.

  • Cihaz form faktörlerinin en yaygın giriş yöntemi olabilir ancak belirli bir cihaz form faktörünün belirli bir giriş türünün kullanımını ima ettiğini varsaymamak önemlidir.

  • Chromebook'ta yerleşik bir dokunmatik yüzey ve klavye bulunur ancak bu giriş türleri yalnızca bu form faktörüne özgü değildir.

  • Fiziksel klavyeler, dokunmatik yüzeyler ve fareler telefonlarda, tabletlerde ve TV'lerde de kullanılabilir. Hatta bazı TV'lerde dokunmatik ekranlar da bulunur.

  • Birden fazla giriş türünü desteklemenin bir diğer önemli nedeni de erişilebilirliktir.

  • Kullanıcıların tercih ettikleri giriş cihazını kullanmalarına ve uygun gördükleri şekilde giriş cihazları arasında geçiş yapmalarına izin vermek, uygulamaları daha erişilebilir ve kullanılabilir hale getirmek için doğru bir yaklaşımdır.

  • Ayrıca yargı alanına bağlı olarak, uygulamanızda bu giriş türleri için (özellikle klavye ve fare gibi cihazlarla ilgili) belirli ve uyumlu davranışlar sunmak yasal bir zorunluluk olabilir.

  • Kısacası, form faktöründen bağımsız olarak farklı giriş türleri için destek oluşturmanız gerekir.

  • Şimdi Jetpack Compose'un, uygulamalarınızın bu kullanıcı ihtiyaçlarını karşılamasına nasıl yardımcı olduğuna bakalım.

  • Compose'un felsefesi, genel olarak bu farklı giriş türlerinin, özel bir şey yapmanıza gerek kalmadan standart bileşenlerle kutudan çıktığı gibi düzgün şekilde davranmasıdır.

  • Ardından, davranışı uygun gördüğünüz şekilde özelleştirmek ve ayarlamak için ihtiyacınız olan araçlara sahip olmalısınız.

  • Bu nedenle, temel platform tarafından desteklenen giriş türleri arttıkça bu giriş türleri için Compose bileşenlerine destek eklemeyi ve yalnızca Compose sürümünüzü güncelleyerek uygulamalarınızın davranışını iyileştirmeyi amaçlıyoruz.

  • Bu konuşmada, Compose'a yakın zamanda eklenen bu tür iki örneğe göz atacağız.

  • İkisi de dokunmatik yüzey benzeri cihazlar olsa da göreceğiniz üzere çok farklı şekillerde kullanılırlar.

  • Dizüstü bilgisayar tarzı dokunmatik yüzeylerle ilgili son çalışmalardan bahsedelim.

  • Dokunmatik yüzey, işaretçi tabanlı bir giriş cihazıdır.

  • Daha açık belirtmek gerekirse dokunmatik yüzey kullandığınızda iki boyutlu koordinatlar elde edersiniz.

  • Ancak dokunmatik ekrandan farklı olarak, parmakların dokunmatik yüzeydeki koordinatları doğrudan kullanıcı arayüzünüzün koordinat alanında değildir.

  • Bunun yerine, dizüstü bilgisayarlardaki dokunmatik yüzeylerde olduğu gibi imleci kontrol etme işlemi uygulanır.

  • Bu çeviri, imleç hızlandırma ve avuç içi reddi gibi karmaşık platform dönüşümlerini içerir.

  • Bu nedenle, Compose tarafında imleç konumuna karşılık gelen ve genellikle fare girişi gibi davranan bir işaretçi elde edersiniz.

  • Android platformundan fareyle üzerine gelme bilgilerini, ikincil veya üçüncül tıklamalar dahil olmak üzere tıklamaları alırız ve tüm bu bilgiler MotionEvent'lerde toplanır.

  • Compose'un en yeni sürümlerinde davranışı nasıl iyileştirdiğimizi anlamak için öncelikle Compose'un bu işaretçi etkinliklerini nasıl daha yakından işlediğine dair genel bir bakışa göz atalım.

İşaretçi girişini işlemenin altı aşaması

  • Bu süreci altı farklı aşamaya ayıracağım ve hepsini sırayla inceleyeceğiz.

  • İlk aşama, MotionEvent'lerin Compose'a taşınmasıdır.

  • Yani Compose, arka planda aslında sadece bir görünümdür. Çok şey yapan, gerçekten karmaşık bir görünüm olsa da sadece bir görünümdür. Bu nedenle, işaretçi girişi için genel Android sisteminde çalışması gerekir.

  • Compose'da bu, normal bir etkinlik içindeki normal bir pencerede bulunan Compose'un Android platformunun MotionEvent'lerini aldığı anlamına gelir.

  • Ardından, Compose'un bunları işlemesi ve işaretçi girişiyle ilgili olarak Compose'da yapmak istediğiniz her şeyi yapması gerekir.

  • İlk aşama, bu MotionEvent'leri Compose'da PointerInputEvent olarak adlandırdığımız dahili, platformdan bağımsız bir temsile dönüştürmektir.

  • Bu dahili bir tür olduğundan doğrudan göremezsiniz.

  • Burada olanların tüm ayrıntılarını görmek isterseniz MotionEventAdapter'a bakabilirsiniz ancak bu ayrıntıları burada atlayacağız.

  • Böylece artık Compose'da MotionEvent'in platformdan bağımsız bir temsili var.

  • Ayrıca, giriş genellikle zaman içinde gerçekleşir.

  • Birbiri ardına çok sayıda giriş etkinliği alırsınız. Bu nedenle, zaman içinde neler olduğunu bilmek gerçekten faydalıdır.

  • Hareketler, hız takibi, eğim algılama gibi özelliklerin her birinin, her zaman diliminde neler olduğunu anlaması gerekir.

  • Bu işleme ardışık düzenindeki bir sonraki aşama, bu zaman bilgisini eklemektir. Bu aşamada, ardışık işaretçi etkinliklerine dayalı olarak bazı ön işlemler yapılır.

  • Kodda bunu, mevcut PointerInputEvent'i alıp öncekiyle birleştirerek zamana duyarlı bir InternalPointerEvent oluşturmak olarak düşünebilirsiniz.

  • Adından da anlaşılacağı üzere bu da başka bir dahili türdür. Ancak bunu, farklı işaretçi kimliklerinin işaretçi girişi değişiklikleriyle eşlendiği bir harita olarak düşünebilirsiniz. PointerInputChanges ise herkese açık bir türdür.

  • İlk örneğimiz bu.

  • Farklı işaretçi kimlikleri hakkında düşünürken fark edebileceğiniz bir şey, artık zamanın takibinin farkında olduğumuz için işaretçi kimliklerinin ne zaman gelip gittiğini de takip edebilmemizdir.

  • Tek bir tane yok.

  • Dokunmatik ekranda birden fazla parmağınız varsa aynı anda birden fazla işaretçiniz olabilir ve bunu yönetmemiz gerekir.

  • Ayrıntılara girmek isterseniz tüm bunları yapan PointerInputChangeEventProducer'a bakabilirsiniz ancak biz bunu atlayacağız.

  • Daha konuşacak çok şeyimiz var.

  • Artık girişin Compose temsili var ve zaman bilgisi içeriyor.

  • Bir sonraki adım, bu etkinlikle ne yapılacağını belirlemektir.

  • Nereye gönderelim?

  • Bu da bizi isabet yolu testine götürür.

  • Şimdi, bir MotionEvent'in gönderildiği ve bu ComposeView'un tüm pencereyi, hatta tüm ekranı doldurduğu bir durum düşünelim.

  • Bunu nereye göndereceğimizi bulmamız gerekiyor.

  • Compose yalnızca bir görünüm olsa da içinde çok sayıda farklı düğüm, düğme ve etkileşimde bulunduğunuz öğe gibi birçok şey var. Bu nedenle, belirli bir konumda gerçekleşen bir etkinliğin nereye gönderileceğini ve hangi düğümün bu etkinlikle ilgilendiğini belirleme işini Compose'da yapmamız gerekiyor.

  • Bu düzen düğümlerinin koordinatları, sınırları ve şekilleri vardır. Bu nedenle, hangisine dokunulduğunu (dokunulduysa) bulmamız gerekir.

  • Ancak bu da en genel görünüm değildir.

  • Etkileşimli öğeleri diğer etkileşimli öğelerin içine yerleştirmeyi sevdiğimiz ortaya çıktı. Örneğin, bir listeye düğme eklemek gibi.

  • Bunu çok sık yaptığımızı fark ettik.

  • Dolayısıyla, buradaki genel durum, belirli bir giriş etkinliğinin, giriş etkinliğinin koordinatlarıyla isabet alan her etkileşimli düğümden geçen tam bir isabet yolu oluşturmasıdır.

  • Bu durumda, iç içe yerleştirme hiyerarşisinde üç öğe bulunur.

  • Yani bir isabet yolumuz var ama bu bile yeterli değil.

  • Birden fazla işaretçi giriş etkinliğimiz ve basılı olabilecek birden fazla işaretçimiz olduğunu söylemiştim.

  • Aslında tam bir isabet yolu ağacına ihtiyacımız var.

  • Birden fazla işaretçiniz olduğunda tek bir isabet yolu yoktur.

  • Bir sonraki aşama, bu isabet yolu ağacını oluşturmak ve güncellemektir.

  • Bu, neler olup bittiğine daha ayrıntılı bir bakış.

  • Sol tarafta görsel olarak düzenlenmiş düğümlerimiz var. Sol altta ise hiyerarşik gösterimi, hangi düğümlerin diğer düğümlerin içinde olduğunu, hangilerinin birbirinin üst veya alt öğesi olduğunu görebilirsiniz.

  • İşaretçi aşağı indiğinde bu isabet yolunu (ağaçtaki tam yolu) takip ederiz ve ardından söz konusu işaretçi için bir isabet yolu elde ederiz.

  • İkinci işaretçiyi aldığımızda bu isabet yolu bir ağaca dönüşür.

  • Diğer ağla aynı düğümlerden bazılarıyla kesişebilir ancak başka düğümlerle de etkileşime girebilir.

  • Sağ tarafta, şu anda kullandığımız isabet yolu ağacını görüyorsunuz.

  • İşaretçiler gelip gidebilir. Bu nedenle, şu anda devam eden her etkinlikle ilgilenen düğümlerin tam listesini aldığımızdan emin olmak için bunu zaman içinde kendimiz sürdürmemiz gerekir.

  • İşte böyle.

  • Bu giriş etkinlikleri için artık bir isabet yolu ağacımız var. Bu da bir sonraki aşamaya geçtiğimiz anlamına geliyor.

  • Artık bu işaretçi girişi etkinliklerini nereye göndereceğimizi ve her bir etkinlikle hangi düğümlerin ilgilendiğini biliyoruz.

  • Bunu bildiğimize göre koordinat dönüşümü yapabiliriz.

  • Düğümünüz kendi yerel koordinat alanında giriş etkinlikleri alırsa çok iyi olur. Böylece bir sürü koordinat matematiği yapmak zorunda kalmazsınız.

  • Bunu öğrendikten sonra işaretçi giriş etkinliğini alıp ilgili düğümün koordinatlarıyla birleştirebiliriz. Bu işlem, hepinize ve işaretçi giriş değiştiricisine gönderilecek herkese açık PointerEvent'i oluşturur.

  • 6. aşamanın son adımı, etkinliği göndermektir.

  • Bu, gerçekleşen bir işaretçi girişi etkinliğidir ve düğüme istediği işlemi yapması için gönderilir.

  • Bunu üç farklı aşamada yaparız.

  • İlk geçiş, ana geçiş ve son geçiş vardır.

  • Üç farklı geçişin olmasının nedeni, düğümlerin birbirleriyle iletişim kurmasına ve belirli işaretçi giriş etkinliklerinin belirli bölümlerine olan ilgiyi iletmesine ve ardından dağıtımın bir parçası olarak bunların farklı bölümlerini kullanmasına olanak tanımasıdır.

  • İlk geçiş, üst öğeden alt öğeye doğru gerçekleşir.

  • Bu özelliğin yararlı olduğu bir örnek, kaydırma kapsayıcısı olabilecek ve kaydırmaya başladığını bilen ve tüm işaretçi etkinliklerinin alt öğelerine ulaşmasını durdurmak isteyen bir dış düzen düğümüdür.

  • Bu, ilk geçişte etkinliğin tüketilmesine olanak tanır ve ardından alt öğeler başka etkinlik almaz.

  • İkinci geçiş, ana geçiştir.

  • Bu, alt öğeden üst öğeye giden tek ilişkidir.

  • Adından da anlaşılacağı üzere bu, işlem yapmak için kullanılan birincil karttır.

  • Örneğin, bir alt öğe bir basma etkinliğini tüketerek tıklama işlemini başlatır ve iç içe tıklanabilir öğeleriniz varsa bu işlemi üst öğelerinden önce yapma şansı elde eder.

  • Son geçiş ise ilk geçişle aynıdır ve üst öğeden alt öğeye doğru ilerler.

  • Bu sayede bir çocuk, ebeveynine bir etkinliğin bir kısmını tükettiğini söyleyebilir.

  • Örneğin, bir alt öğe tıklama işlemini işlemeye başlar ancak üst öğe kaydırma işlemine başlarsa alt öğe, üst öğenin bunu yaptığını görebilir ve işlemeye başladığı tıklama işlemini iptal edebilir.

  • İşte üç geçiş ve altı aşama bunlardır.

  • Bunlar, işaretçi giriş sisteminin üstündeki her şeyin temelini oluşturur.

  • Hareket işleme, kaydırılabilir, sürüklenebilir, tıklanabilir ve tüm özel işaretçi girişleriniz bu temel üzerine inşa edilmiştir.

Dokunmatik yüzey güncellemeleri ve birden fazla parmakla yapılan hareketler

  • Tüm bu bilgilerden sonra, Compose'da dokunmatik yüzey davranışı desteğini nasıl iyileştirdiğimizle ilgili ayrıntılardan biraz bahsedebiliriz.

  • Bu nedenle, Compose 1.12'den önce dokunmatik yüzey giriş etkinlikleri, imleci kontrol etmek için dokunmatik yüzeyle fiziksel olarak etkileşime giren bir parmak olduğundan dokunma işaretçi türü olarak raporlanıyordu.

  • Ancak kullanıcılar, bu giriş türünün fiziksel fareye daha çok benzemesini bekler.

  • Bu nedenle, işaretçi türünü PointerType.Touch yerine PointerType.Mouse olarak değiştirdik.

  • Bu değişiklikle birlikte kullanıcılar, bu bilgileri kullanan tüm bileşenlerde çok daha tutarlı bir şekilde hizalanmış fare ve dokunmatik yüzey deneyimi yaşayacak.

  • İpucu davranışı buna örnek olarak verilebilir. İpuçları için dokunmatik yüzey ve farede muhtemelen aynı davranışı istersiniz.

  • Dokunmatik yüzeyle ilgili yaptığımız ikinci büyük değişiklik, dokunmatik yüzeyde birden fazla parmakla yapılan hareketlerle ilgilidir.

  • Daha önce Compose, Android platformunun akıllı ancak biraz ürkütücü olan sahte parmaklar konseptini kullanıyordu.

  • Bunun ne anlama geldiğine bakalım.

  • Dokunmatik yüzeyde iki parmağınızı kullanarak kaydırdığınızda Android, imlecin bulunduğu yerde aşağı inen tek bir sahte dokunmatik ekran parmağı oluşturur.

  • Ardından, parmaklarınızı dokunmatik yüzeyde hareket ettirdiğinizde dokunmatik ekrandaki sahte parmak, istenen davranışı taklit etmek için doğru mesafe ve yönde hareket eder ve ardından serbest bırakılır.

  • Yani, dokunmatik yüzeyde yukarı doğru hareket eden iki parmak, dokunmatik ekranda yukarı doğru hareket eden tek bir sahte parmağa dönüştürülür ve bu da aşağı kaydırmaya neden olur.

  • Burada eğlenceli bir şey var: Benim gibi ters dokunmatik yüzey kaydırma özelliğini kullanıyorsanız kaydırmanın aslında diğer yöne gitmesini istersiniz.

  • Bunu yapmak için sahte parmağın yönünü tersine çevirmeniz gerekir.

  • Artık dokunmatik yüzeyde iki parmağın yukarı doğru hareketi, dokunmatik ekranda tek bir sahte parmağın aşağı doğru hareketi olarak yorumlanır. Bu da daha öncekinin tam tersi şekilde yukarı kaydırma işlemine neden olur.

  • Ölçeklendirme de benzer şekilde çalışır.

  • Dokunmatik yüzeyde ölçeklendirme yapmak için iki parmağınızı kullandığınızda Android, yakınlaştırma veya uzaklaştırma davranışını taklit etmek için aşağı inen ve ardından harekete bağlı olarak birbirine yaklaşan ya da birbirinden uzaklaşan iki sahte dokunmatik ekran parmağı oluşturur.

  • Bu nedenle, kaydırma için Compose 1.12 ve ölçeklendirme için Compose 1.13'ten itibaren bu sahte parmakları yakalıyoruz.

  • Bunları platformun bize verdiği şekilde göndermeyiz ve yeni işaretçi etkinliği türlerine yeniden yorumlarız: kaydırma için PanStart, PanMove ve PanEnd, ölçeklendirme için ScaleStart, ScaleChange ve ScaleEnd.

  • Bunu, daha önce bahsettiğim Android'den Compose'a etkinlik dönüştürme aşamasında yaparız.

  • Bu nedenle, sahte parmak etkinliklerini uygun türlerine dönüştürür ve ardından bu platformda tanımlanan hareketleri imlece karşılık gelen isabet yoluna göndeririz.

  • Bunun neden önemli olduğuna bakalım.

  • Bunu neden yapıyoruz?

  • Buradaki kutunun, ölçeklendirmek istediğimiz güzel bir resim olduğunu varsayalım.

  • Ölçeklendirme için dokunmatik yüzeyde iki parmak kullanırken iki sahte parmaktan biri öğeyi kaçırabiliyordu.

  • İsabet yolu resimle kesişmez ve sınırların dışında başlar.

  • Bu durumda, resim ölçeklenmek yerine kaydırılır.

  • Ardından, resmin dışında kaydırılabilir başka bir öğe varsa o da birlikte kaydırılmaya başlayabilir.

  • Kullanıcının istediği bu değildi.

  • Ölçeklendirme yapmak istiyordu.

  • Bu nedenle, artık bu sahte parmakları göndermek yerine, ölçeklendirme hareketini yalnızca imleç konumunun altındaki öğeye gönderiyoruz. Bu da doğru davranışın gerçekleşmesini sağlıyor.

  • İmlecin nerede olduğuna veya ölçeklendirmek istediğiniz öğenin kenarına ne kadar yakın olduğuna bakılmaksızın, öğe artık doğru şekilde ölçeklendirilir.

  • Yeniden yorumlanan bu giriş etkinlikleri, kaydırılabilir ve dönüştürülebilir gibi bileşenlerde varsayılan olarak kullanılır. Bu sayede, temel yapı taşlarını kullanıyorsanız dokunmatik yüzey girişleri için daha yüksek kalite davranış elde edebilirsiniz.

  • Bu bileşenlerin üzerine inşa edilmiş bir şey kullanıyorsanız Compose sürümünüzü en yeni sürüme güncelleyerek bu iyileştirilmiş davranıştan yararlanabilirsiniz.

  • Özel işaretçi girişi değiştiricileri yazıyorsanız bu yeni API'lere göz atmanızı ve kullanıcılarınıza tüm bu farklı giriş cihazlarında mümkün olan en iyi deneyimi sunmak için bunları desteklediğinizden emin olmanızı öneririz.

  • Ayrıca, uygulamanızın tüm bu farklı giriş türlerini doğru şekilde işlediğini kontrol edebileceğiniz test API'leri de ekledik.

  • Bu nedenle, performTrackpadInput, fare ve dokunma için mevcut test API'lerine çok benzer.

    onNodeWithContentDescription("Photo")
        .performTrackpadInput {
            click(center)
    
            pan(Offset(0f, 100f))
    
            scale(0.9f)
        }
  • Tüm bunları kullanarak, kullanıcının cihazınızda hangi giriş cihazını kullandığına bakılmaksızın uygulamanızın doğru şekilde çalıştığını doğrulayabilirsiniz.

  • Umarım bu sayede, işaretçi etkinliklerinin dokunmatik alandaki parmaktan uygulamanıza kadar nasıl ulaştığı hakkında daha iyi bir fikir edinmişsinizdir.

  • Şimdi, dokunmatik yüzeylerin çok farklı bir kullanım şeklinden bahsetmesi için sözü Jeremy'ye bırakıyorum.

Dolaylı girişe giriş

  • Teşekkürler.

  • İşte böyle.

  • Merhaba, ben Jeremy Walker.

  • Giriş üzerinde çok çalışıyorum ve Compose girişiyle yaptığımız yeni şeylerden bazılarını ve bunun sizi nasıl etkilediğini anlatmanın ilginç olacağını düşündüm.

  • Özellikle de yeni bir form faktörüne dayalı yeni bir giriş yöntemi olan akıllı gözlükler nedeniyle ortaya çıkan bu dolaylı giriş türüyle ilgili.

  • Gözlükten giriş alırken bunu birkaç şekilde yapabilirsiniz: Bir şeye bakabilir, sesinizi kullanabilir, hareketleri kullanabilirsiniz ancak ben özellikle dokunmatik alandan bahsedeceğim.

  • Bunlar, Alex'in bahsettiklerinden biraz farklı. Başınızın yan tarafında bulunuyorlar, dikey, çok geniş ve son derece kısalar.

  • Bu özelliğin Compose'da nasıl çalışacağını düşünürken önünüzde küçük bir düğme olduğunu ve imleci hareket ettirerek bu düğmeye dokunmaya çalıştığınızı hayal edin. Bu pek de iyi bir deneyim olmaz, değil mi?

  • Peki, bunu nasıl destekleyeceğiz?

  • Gözlük kullanıcı arayüzü bu şekilde görünür.

  • İçerikleri görüş alanınıza sorunsuz bir şekilde yerleştirmek için özel olarak tasarlanmıştır.

  • Ama çok basit, yani basit tutmaya çalışıyoruz.

  • Buradaki örneğe bakarsak bunun bir liste olduğunu görebilirsiniz.

  • Merkezdeki belirli bir öğeye odaklanmış.

  • Asıl yapmak istediğimiz şey ne?

  • Bu öğeyi seçmek veya önceki ya da sonraki öğeye geçmek istiyoruz.

  • Ekran konumuna ihtiyacımız yoktur.

  • Bu biraz daha karmaşık ama temelde üç seçenek olduğunu görebilirsiniz: Telefonu kapatabilir, sesi açabilir veya videoyu kapatabilirsiniz.

  • Ancak aslında, bu öğeyi seçmek veya başka bir öğeye geçip onu seçmek istiyorsunuz.

  • Bu nedenle, ekrandaki bir konumu veya bu durumda gözlerinizi doğrudan eşlememize gerek olmadığını düşünüyoruz.

  • Evet, aslında böyle görünüyor.

  • Örnek vermek gerekirse, burada öğeler arasında geçiş yaptığımı görebilirsiniz. Bu, Gözlük kullanıcı arayüzünde gerçekleşiyor ve istediğimiz şeye uyuyor.

  • Bu simgeye dokunabilirsiniz.

  • Bunu desteklemek için neler yapabileceğimizi düşünürken Android'e baktık.

  • Ve eğer siz de... Pardon.

  • Bu, burada ileri atlıyor.

  • Geri dönelim.

  • İşte başlıyoruz.

  • İşte böyle.

  • Bu cihazlardan birini kullanıp Android cihazla bağladıysanız kullanıcı arayüzü öğelerini birinden diğerine kolayca taşıyabileceğinizi biliyorsunuzdur.

  • Örneğin, uzaktan kumandayla Google TV'ye bağlı bir cihazda film listesini görebilir, ok düğmelerine basarak istediğiniz filme gidebilir ve tamam düğmesine basarak seçebilirsiniz.

  • Oyun menünüz varsa ve bu kumandayı kullanıyorsanız menüdeki bir kullanıcı arayüzü öğesine gitmek için d-pad'i veya joystick'i kullanabilir ve öğeyi seçebilirsiniz.

  • Aynı durum klavye için de geçerlidir.

  • Bu, Compose'da istediğimizle eşleşiyor.

  • Nasıl göründüğü hakkında fikir edinmeniz için bunları tekrar gösteriyorum.

  • Biraz daha geriye gidersek TV ile eşlenen bir dokunmatik alan türü vardı. Bu tür, gezinme dokunuşu denen bir özellik kullanıyordu.

  • Buradaki fikir, x ve y koordinatlarının ekrana hiç bağlı olmamasıdır.

  • Yalnızca hareket algılama için kullanılır.

  • Sağa kaydırdığınızda, beğen düğmesine basmış gibi olursunuz.

  • Sola kaydırırsanız sola, yukarı ve aşağı gidersiniz.

  • Bu, istediğimiz sonucu büyük ölçüde veriyor.

  • Sürükleme ve kaydırma gibi hareketleri anlamak için yalnızca x ve y'yi kullanırsınız. Bu da Compose'u kullanmaya başlamak için ihtiyacımız olan bilgilerin çoğunu sağlar.

  • Tam olarak aynı değil çünkü TV'ye göre ayarlanmış. Bu nedenle TV yolunu seçmediğimizden, daha sonra TV'leri bozmadığımızdan emin olmamız gerekiyor. Bu yüzden bunları ayırmamız gerekiyor ancak buna birazdan değineceğiz.

  • Ancak bize bir başlangıç noktası sunar.

  • Bu sayede bu tür dokunma hareketleriyle gezinmeyi kullanabiliriz.

Dolaylı giriş ve yeni form faktörleri için API tasarımı

  • Evet.

  • API tasarımı nasıl olacak?

  • Compose'da en genel veya en yaygın giriş dokunmadır, değil mi?

  • Bu konuda çok çalışıyoruz.

  • Bu nedenle, bununla nasıl bir ilişkisi olduğunu anlamamız gerekiyordu.

  • Hatırlatmak gerekirse PointerEvent şu şekilde görünür.

  • Burada, yukarı hareketin aşağı türü olan bir tür olduğunu ve ardından yalnızca bir liste olan bu PointerInputChange'e sahip olduğunuzu görebilirsiniz. Bunu parmaklar olarak düşünebilirsiniz.

  • Üç parmağınızı indirdiyseniz listede üç öğe olacak.

  • Bu yüzden buna çok benzemesini istedik.

  • Bu, çoğu geliştiricinin girişle ilgilenirken kullandığı modülden çok daha düşük bir modül olan kullanıcı arayüzü modülü değildir.

  • Temel katmanın üstünde bir katman olacaklar.

  • Tüm hareket algılayıcılarımız burada bulunur.

  • Çünkü geliştiriciler olarak, dakika girişi gibi tüm bu ayrıntılarla ilgilenmezsiniz.

  • Sadece sürükleme, tıklama veya kaydırma işleminin gerçekleşip gerçekleşmediğini bilmek istersiniz ve işleminizi buna göre yaparsınız.

  • Bu işlemi sizin için gerçekleştiren bir dizi kodumuz var ve bu kodlar arka planda bu teknolojilerle destekleniyor.

  • Bu nedenle, temel koddaki bu yeni türleri desteklemeyi mümkün olduğunca kolaylaştırmamız gerektiğini düşündük.

  • Bu nedenle, hemen hemen aynı görünen yeni bir tür oluşturduk.

  • Buna dolaylı denir.

  • Dolaylı etkileşim ise ekrana doğrudan dokunulmadığı anlamına gelir.

  • Bu nedenle, bu özelliğin geleceğini size bildirir. Bu özelliği dokunma açısından düşünmeyin.

  • Burada yalnızca hareketleri işlediğimizi ve kullanıcı arayüzü öğeleri arasında gezindiğimizi düşünün.

  • Tür aynı.

  • Parmakların listesi var.

  • Bu durumda IndirectPointerInputChange'dir.

  • Bunları yaptık ve çok iyi sonuç aldık.

  • Ancak daha sonra, Birincil Yönlü Hareket Ekseni adında bir öğeyle daha karşılaştık.

  • Bu biraz uzun bir tanım ama açıkladığımda mantıklı gelecek. Çünkü bu tanımın ortaya çıkış hikayesi oldukça ilginç.

  • Peki, bu nasıl oldu?

  • Başınızın yan tarafında geniş ve kısa bir dokunmatik alan bulunur.

  • Bu noktada, dokunmatik gezinme özelliğimiz var diye düşündük.

  • Yani sola ve sağa kaydırabiliriz.

  • Bu da iyi bir yöntem.

  • Ancak dokunmatik yüzeylerin günümüzdeki durumunu düşünürseniz

  • Sola veya sağa gittiğinizde, kullanıcı arayüzü içeriğinizle birlikte dokunmatik yüzeyde sola veya sağa gidersiniz.

  • Yukarı veya aşağı giderseniz listeyi yukarı veya aşağı kaydırırsınız.

  • Bunu gözlükle yapmaya çalışırsanız, fena değil, değil mi?

  • Ancak bunu yapıyorsanız bu iyi bir deneyim değildir.

  • En doğal hareketin dokunma olduğunu gördük. Ancak gözlüğün yan tarafında kaydırma hareketi de yapabilirsiniz.

  • Kullanıcılarla bir dizi çalışma yaptık ve yatay olarak kaydırdığınızda içeriği yatay olarak değil, dikey olarak hareket ettirdiğinizi beklediklerini gördük.

  • Bunu zihninizde canlandırabilirsiniz. Örneğin, burada kaydırma yaparken önünüzde bir liste varsa ileri doğru kaydırarak listede ilerleyebilir veya geri doğru kaydırarak listede geriye gidebilirsiniz.

  • Yani iki boyutlu bir girişi alıp tek boyutlu bir şekilde düşünmeye çalışıyoruz.

  • Birincil Hareket Ekseni fikri de buradan çıktı. Yatay olarak hareket ettirdiğinizde dikey olarak hareket eder.

  • Bu nedenle, cihazın kendisinde belirtebilirsiniz.

  • "Bu normal bir dokunmatik yüzey değil." diyebilirsiniz.

  • Birincil yönün yatay olmasını istiyorum. Bu, ilerlemek istediğim tek eksen.

  • Bu fikir de buradan çıktı.

  • Anladım.

  • Bu konuda kendimize güveniyoruz.

  • Oluşturma her şeyi hallediyor.

  • Bu dikey uygulama da oldukça başarılı.

  • Bu konuyu düşünebilirsiniz.

  • Yatay tanımla eşlediğimizde yalnızca ileri ve geri düğmeleri bulunur.

  • Yukarı, aşağı, sol, sağ yok.

  • Yalnızca ileri ve geri düğmeleri var.

  • Ardından, sonraki ve önceki öğelere odaklanma konusunda bilgi sahibiyseniz bunu eşleyebiliriz.

  • Şimdi sonraki ve önceki öğeye geçelim.

  • Bu, dikey videolar için çok uygundur.

  • Üstelik daha da güzel.

  • Yatay olarak da çalışıyor, değil mi?

  • Çünkü odaklanılan bir sürü öğeniz var.

  • Sonraki veya önceki slayta geçebilirsiniz. Her ikisinde de çalışır.

  • Bu, Compose'da tanımladığımız ve çözdüğümüz bir durum. Ancak cihazın kendisi bunu söyleyebilseydi çok iyi olurdu. Çünkü cihaz, şeklin garip olup olmadığını ve yalnızca bu birincil ekseni isteyip istemediğini bilir ancak bunu tanımlamanın bir yolu yoktur.

  • Bu nedenle, bu konsepti platforma geri götürüp platformda tanımlamamız gerekti. Böylece bunu standartlaştırabiliriz ve bu cihazlar bunu kendileri belirtebilir. Böylece Compose bunu tamamen destekleyebilir.

  • Yani Compose'da çalışıp ilerlediğimiz ve geriye dönüp çalıştığımız ve bir nevi yanımızda getirdiğimiz bir durum var.

  • Biz de tam olarak bunu yaptık.

  • Bu yeni API'yi, sizin veya cihazın bunu belirtebilmesi için oluşturduk.

    InputDevice.ViewBehavior
    .getPrimaryDirectionalMotionAxis()
  • Daha önce dokunmatik girişten veya dokunmatik gezinmeden bahsettiğimde, bunun esas olarak TV'ler için tasarlandığını söylemiştim.

  • Bu uygulamaları bozmak istemedik.

  • Bu nedenle, yeni cam giriş türünü belirtmek için başka bir alan ekledik.

  • Anladım.

  • Peki, bu sizin için ne anlama geliyor?

  • Bu, hareket algılayıcı olarak elde ettiğiniz şeyin daha spesifik bir versiyonudur.

    // Glimmer Library
    Box(
        modifier =
            Modifier.fillMaxSize()
                .onIndirectPointerGesture(
                    enabled = true,
                    onSwipeForward = { /* onSwipeForward */ },
                    onSwipeBackward = { /* onSwipeBackward */ },
                    onClick = { /* onClick */ },
                )
                .focusTarget()
    ) {
        // App()
  • Foundation kullanıyorsanız hareket algılayıcılarla çalışır.

  • Bu işlemi sizin için gerçekleştirdik. Herhangi bir işlem yapmanız gerekmez.

  • Ancak gözlük için bir uygulama yapmak istiyorsanız Glimmer kitaplığımızı kullanabilirsiniz. Ayrıca özel bir hareket algılayıcımız da var. Bu algılayıcı size yalnızca tıklama, ileri kare ve geri kareyi verir. Yani bunları birleştirmeniz gerekmez, yalnızca bu algılayıcıyı kullanabilirsiniz.

Dolaylı işaretçi girişi test ediliyor

  • Anladım.

  • API'nin platformda ve Compose'da nasıl çalıştığını ele aldık.

  • Test etme hakkında

  • Dokunma testi yapmak istediğinizde dokunma bu şekilde görünür.

    @Test
    clickTest {
    
    rule.onNodeWithTag(defaultTag)
    .performTouchInput
    { click(center) }
    
    }
  • performTouchInput dedikten sonra bir hareket yapmanız yeterli.

  • Çok sayıda farklı hareket var ve hareketi gerçekleştirmek için tüm küçük etkinlikleri oluşturuyoruz.

  • Bu süreç genel olarak nasıl işler?

  • Compose kullanıcı arayüzü modülü ve kullanıcı arayüzü test modülü var. Bunlar, en azından giriş açısından MotionEvent'leri kullanarak iletişim kuruyor.

  • Ayrıca, kullanıcı arayüzü testi modülü, MotionEvent'e dayalı bir sıraya alma mekanizması da kullanır.

  • Bunu size neden anlatıyorum?

  • Çünkü dolaylı giriş etkinliği gibi bir MotionEvent'i programatik olarak oluşturamazsınız. Bu benim için harika bir şeydi çünkü modüller ile sıraya alma sistemi arasındaki tüm iletişimi yeniden yazmam gerekiyordu.

  • Ama başardım.

  • Peki, bu sizin için ne anlama geliyor?

  • Dokunmatik giriş testine alışkınsanız dolaylı giriş için bu sonuçları elde edersiniz.

  • Adın başına "dolaylı" kelimesini eklemeniz yeterlidir.

    @Test
    clickTest {
    
    rule.onNodeWithTag(defaultTag)
    // .performTouchInput
    .performIndirectPointerInput (
    IndirectPointerEventPrimaryDirectionalMotionAxis.X,
    inputDeviceSize,
    )
    { click(center) }
    }
  • Şimdi, bazı ek parametreler iletiyorum.

  • İlkini muhtemelen tanıyorsunuzdur. Sektörü burada belirtirsiniz.

  • Giriş boyutu da doğal olarak dokunmatik alanın boyutu olur.

  • Bu durum pek bir şeyi değiştirmez.

  • Kaynak koduna bakarsanız yazdığım uzantı işlevini görebilirsiniz. Bu işlev şu şekilde görünür.

    @Test
    clickTest {
    
    rule.onNodeWithTag(defaultTag)
    // .performTouchInput
    .performIndirectPointerInput
    { click(center) }
    
    }
  • Anladım.

  • Bu sayede, gözlük çerçevelerinizde veya akıllı gözlüklerinizde dokunmatik yüzeyleri desteklemek için yaptığımız tüm çalışmalar hakkında fikir edinebilirsiniz.

  • Ancak bu egzersizleri göz ve el takibi için de yapıyorum. Dolayısıyla, daha fazlası da gelecek.

  • Özetle, benim anlattıklarımdan neleri hatırlamanızı istiyorum?

Özet ve önemli noktalar

  • Dolayısıyla, telefon, gözlük veya başka bir girişle dokunmatik yüzey kullanıyorsanız bunu düşünüyor ve çalışmayı önceden yapmaya çalışıyoruz.

  • Bu nedenle, bu Foundation hareket algılayıcılarını kullanıyorsanız hemen çalışır.

  • Bu birinci kural.

  • İkincisi, Compose birincil kullanıcı arayüzü araç setidir. Hem platformda hem de araç setinde yeni giriş türlerini keşfetmeye ve desteklemeye devam edeceğiz. Burada yaptığım da buydu.

  • Ayrıca, API'leri test etmek için tanıdık bir yüzey ve paradigma kullanmak istiyorum. Böylece bu yeni türleri taşımak ve test etmek sizin için mümkün olduğunca kolay olur.

  • Teşekkürler, umarım bu bilgiler işinize yaramıştır.

Kod

Kod snippet'leri

"Dokunmatik yüzey güncellemeleri ve birden fazla parmakla yapılan hareketler" bölümünde 15:47'deki Kotlin snippet'i
onNodeWithContentDescription("Photo")
    .performTrackpadInput {
        click(center)

        pan(Offset(0f, 100f))

        scale(0.9f)
    }
"Dolaylı giriş ve yeni form faktörleri için API tasarımı" videosunda 25:08'deki Kotlin snippet'i
InputDevice.ViewBehavior
.getPrimaryDirectionalMotionAxis()
"Dolaylı giriş ve yeni form faktörleri için API tasarımı" videosunda 25:32'deki Kotlin snippet'i
// Glimmer Library
Box(
    modifier =
        Modifier.fillMaxSize()
            .onIndirectPointerGesture(
                enabled = true,
                onSwipeForward = { /* onSwipeForward */ },
                onSwipeBackward = { /* onSwipeBackward */ },
                onClick = { /* onClick */ },
            )
            .focusTarget()
) {
    // App()
"Dolaylı işaretçi girişini test etme" bölümünde 26:11'deki Kotlin snippet'i
@Test
clickTest {

rule.onNodeWithTag(defaultTag)
.performTouchInput
{ click(center) }

}
"Dolaylı işaretçi girişini test etme" bölümünde 27:08'deki Kotlin snippet'i
@Test
clickTest {

rule.onNodeWithTag(defaultTag)
// .performTouchInput
.performIndirectPointerInput (
IndirectPointerEventPrimaryDirectionalMotionAxis.X,
inputDeviceSize,
)
{ click(center) }
}
"Dolaylı işaretçi girişini test etme" bölümünde 27:23'teki Kotlin snippet'i
@Test
clickTest {

rule.onNodeWithTag(defaultTag)
// .performTouchInput
.performIndirectPointerInput
{ click(center) }

}