Özel bir görünümü etkileşimli hale getirme

"Oluştur" yöntemini deneyin
Jetpack Compose, Android için önerilen kullanıcı arayüzü araç setidir. Compose'da düzenlerle nasıl çalışacağınızı öğrenin.

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 hayattaki aksiyona çok benzer bir şekilde yanıt vermesini sağlamanız gerekir.

Uygulamanızdaki nesnelerin gerçek nesneler gibi davranmasını sağlayın. Örneğin, uygulamanızdaki görsellerin var olup başka yerlerde tekrar görünmesine izin vermeyin. Gerçek dünyadaki nesneler bunu yapmaz. Bunun yerine, resimlerinizi bir yerden başka bir yere taşıyabilirsiniz.

Kullanıcılar, arayüzde oldukça hassas bir davranış veya hissettiğini hisseder ve gerçek dünyayı taklit eden inceliklere en iyi şekilde tepki verir. Örneğin, kullanıcılar bir kullanıcı arayüzü nesnesini salladığında, başta hareketi geciktiren eylemsizlik hissi verin. Hareketin sonunda, izleyiciye nesneyi hareketin ötesine taşıyan bir momentum hissi verin.

Bu sayfada, bu gerçek dünyadaki davranışları özel görünümünüze eklemek için Android çerçevesinin özelliklerinin nasıl kullanılacağı gösterilmektedir.

İlgili daha fazla bilgiyi Giriş etkinliklerine genel bakış ve Mülk animasyonuna genel bakış bölümlerinde bulabilirsiniz.

Giriş hareketlerini işleme

Diğer birçok kullanıcı arayüzü çerçevesi gibi Android de bir giriş etkinliği modelini destekler. Kullanıcı işlemleri, geri çağırmaları tetikleyen etkinliklere dönüşür ve geri çağırmaları geçersiz kılarak uygulamanızın kullanıcıya nasıl yanıt vereceğini özelleştirebilirsiniz. Android sisteminde en yaygın giriş etkinliği, onTouchEvent(android.view.MotionEvent) özelliğini tetikleyen dokunma etkinliğidir. Etkinliği işlemek için bu yöntemi aşağıdaki gibi 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 kullanışlı değildir. Modern dokunmatik kullanıcı arayüzleri; dokunma, çekme, itme, hızla kaydırma ve yakınlaştırma gibi hareketler açısından etkileşimleri tanımlar. Android, ham dokunma etkinliklerini hareketlere dönüştürmek için GestureDetector özelliğini sunar.

GestureDetector.OnGestureListener uygulayan bir sınıfın örneğini ileterek bir GestureDetector oluşturun. Yalnızca birkaç hareketi işlemek istiyorsanız GestureDetector.OnGestureListener arayüzünü uygulamak yerine GestureDetector.SimpleOnGestureListener aracı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 kullanmasanız da her zaman true döndüren bir onDown() yöntemi uygulayın. Tüm hareketler bir onDown() mesajıyla başladığından bu gereklidir. GestureDetector.SimpleOnGestureListener gibi onDown() uygulamasından false değerini döndürürseniz sistem, hareketin geri kalanını yoksaymak istediğinizi varsayar ve GestureDetector.OnGestureListener öğesinin diğer yöntemleri çağrılmaz. Yalnızca bir hareketin tamamını yoksaymak istiyorsanız onDown() öğesinden false değerini döndürün.

GestureDetector.OnGestureListener öğesini uyguladıktan ve GestureDetector örneğini oluşturduktan sonra, onTouchEvent() içinde aldığınız dokunma etkinliklerini yorumlamak için GestureDetector öğenizi kullanabilirsiniz.

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;
}

Bir hareketin parçası olarak tanımadığı bir dokunma etkinliğini onTouchEvent() ilettiğinizde false değerini döndürür. Daha sonra kendi özel hareket algılama kodunuzu çalıştırabilirsiniz.

Fiziksel olarak makul bir hareket yaratın

Hareketler, dokunmatik ekranlı cihazları kontrol etmenin güçlü bir yoludur ancak fiziksel olarak makul sonuçlar üretmedikleri sürece mantıksız gelebilir ve hatırlamaları zor olabilir.

Örneğin, görünümde çizilen öğeyi dikey ekseninde dönen yönde ayarlayan bir yatay sallama hareketi uygulamak istediğinizi varsayalım. Kullanıcı arayüzü hızla dönüş yönünde hareket edip ardından yavaşlayarak (kullanıcı bir volanı itip döner gibi) yanıt verirse bu hareketin anlamı olur.

Bir kaydırma hareketini nasıl canlandıracağınız hakkındaki dokümanlarda, kendi scoll davranışınızı nasıl uygulayacağınız hakkında ayrıntılı bir açıklama yer almaktadır. Ancak vola hissini simüle etmek de sıradan bir iş değil. Volan modelinin doğru çalışması için çok miktarda fizik ve matematik 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ı, volkan tarzı hızla fırlatma hareketlerinin işlenmesinin temelini oluşturur.

Bir hızlı fiş başlatmak için başlangıç hızı ile flaşın minimum ve maksimum x ve y değerleriyle 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ı hamlenin fizik modelini oluşturur. Daha sonra düzenli aralıklarla Scroller.computeScrollOffset() çağrısı yaparak Scroller özelliğini güncelleyin. computeScrollOffset(), geçerli saati okuyup fizik modelini kullanarak Scroller nesnesinin dahili durumunu günceller. Böylece o andaki x ve y konumlarını hesaplar. Bu değerleri almak için getCurrX() ve getCurrY() arayabilir.

Çoğu görünüm, Scroller nesnesinin x ve y konumlarını doğrudan scrollTo() öğesine iletir. Bu örnek biraz farklıdır: Görünümün dönme açısını ayarlamak için geçerli 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 pürüzsüz görünmesi için yeterli sıklıkta yeni koordinatları uygulayın. Bunu yapmanın iki yolu vardır:

  • fling() çağrısından sonra postInvalidate() yöntemini çağırarak yeniden çekme işlemini zorunlu kılın. Bu teknik, onDraw() içinde kaydırma ofsetlerini hesaplamanızı ve kaydırma ofseti her değiştiğinde postInvalidate() çağrısı yapmanızı gerektirir.
  • Kısa süreli animasyon süresince animasyon uygulamak için bir ValueAnimator ayarlayın ve addUpdateListener() yöntemini çağırarak animasyon güncellemelerini işlemesi için bir işleyici ekleyin. Bu teknik, View özelliklerini canlandırmanızı sağlar.

Geçişlerinizi akıcı hale getirin

Kullanıcılar, modern bir kullanıcı arayüzünün durumlar arasında sorunsuz bir şekilde geçiş yapmasını bekliyor: Kullanıcı arayüzü öğeleri görünüp kaybolmak yerine soluklaşıyor ve aniden başlayıp aniden durmak yerine sorunsuz başlayıp sona eren hareketler. Android özelliği animasyon çerçevesi yumuşak geçişleri kolaylaştırır.

Animasyon sistemini kullanmak için bir özellikte görünümünüzü etkileyen bir değişiklik olduğunda, özelliği doğrudan değiştirmeyin. Bunun yerine, değişikliği yapmak için ValueAnimator işlevini kullanın. Aşağıdaki örnekte, görünümdeki seçili alt bileşenin değiştirilmesi, oluşturulan görünümün tamamının döndürülmesini ve seçim işaretçisinin ortalanmasını sağlar. ValueAnimator, yeni döndürme değerini hemen ayarlamak yerine döndürmeyi birkaç yüz milisaniyelik süre boyunca 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 özelliklerinden biriyse animasyon oluşturmak daha da kolaydır. Çünkü görünümlerde, aşağıdaki örnekte olduğu gibi, aynı anda birden çok mülkün eş zamanlı animasyonu için optimize edilmiş yerleşik bir ViewPropertyAnimator yerleşik yerleşik olarak bulunur.

Kotlin

animate()
    .rotation(targetAngle)
    .duration = ANIM_DURATION
    .start()

Java

animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();