Kullanıcı arayüzü çizmek, özel görünüm oluşturmanın yalnızca bir parçasıdır. Ayrıca, görünümünüzün kullanıcı girişine, taklit ettiğiniz gerçek dünya işlemine çok benzeyecek şekilde yanıt vermesini sağlamanız gerekir.
Uygulamanızdaki nesnelerin gerçek nesneler gibi davranmasını sağlayın. Örneğin, gerçek dünyadaki nesneler bunu yapmadığı için uygulamanızdaki resimlerin yok olup başka bir yerde yeniden görünmesine izin vermeyin. Bunun yerine, resimlerinizi bir yerden başka bir yere taşıyın.
Kullanıcılar, arayüzdeki en ufak davranışları veya hisleri bile algılar ve gerçek dünyayı taklit eden ayrıntılara en iyi tepkiyi verir. Örneğin, kullanıcılar bir kullanıcı arayüzü nesnesini hızlı kaydırdığında başlangıçta hareketi geciktiren bir atalet hissi verin. Hareketin sonunda, nesneyi fırlatmanın ötesine taşıyacak bir momentum hissi verin.
Bu sayfada, Android çerçevesinin özelliklerini kullanarak bu gerçek dünya davranışlarını özel görünümünüze nasıl ekleyeceğiniz gösterilmektedir.
İlgili ek bilgileri Giriş etkinliklerine genel bakış ve Özellik animasyonuna genel bakış başlıklı makalelerde bulabilirsiniz.
Giriş hareketlerini işleme
Android, diğer birçok kullanıcı arayüzü çerçevesi gibi bir giriş etkinliği modelini destekler. Kullanıcı işlemleri, geri çağırmaları tetikleyen etkinliklere dönüşür ve uygulamanızın kullanıcıya nasıl yanıt vereceğini özelleştirmek için geri çağırmaları geçersiz kılabilirsiniz. Android sistemindeki en yaygın giriş etkinliği dokunma'dır ve onTouchEvent(android.view.MotionEvent) tetikler.
Etkinliği işlemek için bu yöntemi aşağıdaki şekilde geçersiz kılın:
Kotlin
override fun onTouchEvent(event: MotionEvent): Boolean { return super.onTouchEvent(event) }
Java
@Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }
Dokunma etkinlikleri tek başına pek yararlı değildir. Modern dokunmatik kullanıcı arayüzleri, etkileşimleri dokunma, çekme, itme, fırlatma ve yakınlaştırma gibi hareketler açısından tanımlar. Android, ham dokunma etkinliklerini hareketlere dönüştürmek için GestureDetector sağlar.
GestureDetector uygulayan bir sınıfın örneğini ileterek GestureDetector.OnGestureListener oluşturun.
Yalnızca birkaç hareketi işlemek istiyorsanız GestureDetector.SimpleOnGestureListener arayüzünü uygulamak yerine GestureDetector.OnGestureListener arayüzünü genişletebilirsiniz. Örneğin, bu kod, GestureDetector.SimpleOnGestureListener öğesini genişleten ve onDown(MotionEvent) öğesini geçersiz kılan bir sınıf oluşturur.
Kotlin
private val myListener = object : GestureDetector.SimpleOnGestureListener() { override fun onDown(e: MotionEvent): Boolean { return true } } private val detector: GestureDetector = GestureDetector(context, myListener)
Java
class MyListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return true; } } detector = new GestureDetector(getContext(), new MyListener());
GestureDetector.SimpleOnGestureListener kullanıp kullanmadığınıza bakılmaksızın, her zaman true döndüren bir onDown() yöntemi uygulayın. Tüm hareketler onDown() mesajıyla başladığı için bu gereklidir. false değerini onDown() işlevinden GestureDetector.SimpleOnGestureListener işlevinde olduğu gibi döndürürseniz sistem, hareketin geri kalanını yoksaymak istediğinizi varsayar ve GestureDetector.OnGestureListener işlevinin diğer yöntemleri çağrılmaz. Yalnızca false değerini döndürün. Bir hareketin tamamını yoksaymak istiyorsanız onDown() değerini döndürün.
GestureDetector.OnGestureListener hizmetini uygulayıp GestureDetector.OnGestureListener örneği oluşturduktan sonra, onTouchEvent() içinde aldığınız dokunma etkinliklerini yorumlamak için GestureDetector hizmetinizi kullanabilirsiniz.GestureDetector
Kotlin
override fun onTouchEvent(event: MotionEvent): Boolean { return detector.onTouchEvent(event).let { result -> if (!result) { if (event.action == MotionEvent.ACTION_UP) { stopScrolling() true } else false } else true } }
Java
@Override public boolean onTouchEvent(MotionEvent event) { boolean result = detector.onTouchEvent(event); if (!result) { if (event.getAction() == MotionEvent.ACTION_UP) { stopScrolling(); result = true; } } return result; }
onTouchEvent() dokunma etkinliği ilettiğinizde, bu etkinlik hareketin bir parçası olarak tanınmadığı için false döndürülür. Ardından kendi özel hareket algılama kodunuzu çalıştırabilirsiniz.
Fiziksel olarak makul hareketler oluşturma
Hareketler, dokunmatik ekranlı cihazları kontrol etmenin güçlü bir yoludur ancak fiziksel olarak makul sonuçlar üretmedikleri sürece sezgisel olmayabilir ve hatırlanması zor olabilir.
Örneğin, görünümde çizilen öğenin dikey ekseni etrafında dönmesini sağlayan yatay hızlı kaydırma hareketi uygulamak istediğinizi varsayalım. Bu hareket, kullanıcı arayüzü hızlı kaydırma yönünde hızlıca hareket ederek, ardından yavaşlayarak yanıt veriyorsa (kullanıcı bir volana basıp döndürüyormuş gibi) anlamlıdır.
Kaydırma hareketini animasyonla gösterme ile ilgili dokümanlarda, kendi kaydırma davranışınızı nasıl uygulayacağınız hakkında ayrıntılı bir açıklama verilmektedir. Ancak volanın hissini simüle etmek kolay değildir. Bir volan modelinin doğru çalışması için çok fazla fizik ve matematik bilgisi gerekir. Neyse ki Android, bu ve diğer davranışları simüle etmek için yardımcı sınıflar sağlar. Scroller sınıfı, flywheel tarzı hızlı kaydırma hareketlerinin işlenmesinin temelini oluşturur.
Hızlı kaydırma başlatmak için başlangıç hızıyla birlikte x ve y değerlerinin minimum ve maksimum değerlerini kullanarak fling() çağrısı yapın. Hız değeri için GestureDetector tarafından hesaplanan değeri kullanabilirsiniz.
Kotlin
fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { scroller.fling( currentX, currentY, (velocityX / SCALE).toInt(), (velocityY / SCALE).toInt(), minX, minY, maxX, maxY ) postInvalidate() return true }
Java
@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { scroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY); postInvalidate(); return true; }
fling() çağrısı, hızlı kaydırma hareketi için fizik modelini ayarlar. Ardından, düzenli aralıklarla Scroller.computeScrollOffset() işlevini çağırarak Scroller değerini güncelleyin. computeScrollOffset(), geçerli saati okuyarak ve o sırada x ve y konumunu hesaplamak için fizik modelini kullanarak Scroller nesnesinin dahili durumunu günceller. Bu değerleri almak için
getCurrX()
ve
getCurrY()
işlevini çağırın.
Çoğu görünüm, Scroller nesnesinin x ve y konumlarını doğrudan scrollTo()'ye iletir.
Bu örnek biraz farklıdır: Görünümün dönme açısını ayarlamak için mevcut kaydırma x konumunu kullanır.
Kotlin
scroller.apply { if (!isFinished) { computeScrollOffset() setItemRotation(currX) } }
Java
if (!scroller.isFinished()) { scroller.computeScrollOffset(); setItemRotation(scroller.getCurrX()); }
Scroller sınıfı, kaydırma konumlarını sizin için hesaplar ancak bu konumları görünümünüze otomatik olarak uygulamaz. Kaydırma animasyonunun sorunsuz görünmesi için yeni koordinatları yeterince sık uygulayın. Bunu yapmanın iki yolu vardır:
fling()işlevini çağırdıktan sonrapostInvalidate()işlevini çağırarak yeniden çizimi zorunlu kılın. Bu teknik,onDraw()içinde kaydırma telafilerini hesaplamanızı ve kaydırma telafisi her değiştiğindepostInvalidate()işlevini çağırmanızı gerektirir.- Fırlatma süresi boyunca animasyon oluşturmak için bir
ValueAnimatorayarlayın veaddUpdateListener()işlevini çağırarak animasyon güncellemelerini işleyecek bir dinleyici ekleyin. Bu teknik,Viewözelliklerini canlandırmanıza olanak tanır.
Geçişlerinizi sorunsuz hale getirme
Kullanıcılar, modern bir kullanıcı arayüzünün durumlar arasında sorunsuz bir şekilde geçiş yapmasını bekler. Örneğin, kullanıcı arayüzü öğeleri görünmek ve kaybolmak yerine yavaş yavaş görünür ve kaybolur. Hareketler de aniden başlayıp durmak yerine sorunsuz bir şekilde başlar ve sona erer. Android özellik animasyonu çerçevesi, akıcı geçişleri kolaylaştırır.
Animasyon sistemini kullanmak için görünümünüzün görünümünü etkileyen bir özellik her değiştiğinde özelliği doğrudan değiştirmeyin. Bunun yerine, değişikliği yapmak için ValueAnimator kullanın. Aşağıdaki örnekte, görünümde seçilen alt bileşenin değiştirilmesi, seçilen işaretçinin ortalanması için oluşturulan görünümün tamamının döndürülmesine neden olur.
ValueAnimator, yeni dönüşüm değerini hemen ayarlamak yerine birkaç yüz milisaniye içinde dönüşümü değiştirir.
Kotlin
autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0).apply { setIntValues(targetAngle) duration = AUTOCENTER_ANIM_DURATION start() }
Java
autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0); autoCenterAnimator.setIntValues(targetAngle); autoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION); autoCenterAnimator.start();
Değiştirmek istediğiniz değer temel View
özelliklerden biriyse animasyon yapmak daha da kolaydır. Çünkü görünümlerde, aşağıdaki örnekte olduğu gibi birden fazla özelliğin aynı anda animasyonu için optimize edilmiş yerleşik bir ViewPropertyAnimator
bulunur:
Kotlin
animate() .rotation(targetAngle) .duration = ANIM_DURATION .start()
Java
animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();