Kullanıcının ilgisini çeken eğlenceli tasarımlar çoğu zaman projeye olumlu kazanımlar sağlamaktadır.
Bu makalemizde Android uygulamadaki metine Reveal animasyonu ekleyerek, metnin görünmez halinden görünürlüğünü artırarak ortaya çıkmasını ve gizlenmesini sağlayan animasyonu örnekleyeceğim.
Reveal animasyonu birçok projenin UI/UX tasarımlarında kullanılmaktadır. Örneğin, WhatsApp mesaj bölümündeki ataç simgesine dokunduğunuzda oluşan animasyon Reveal’dır.
Örneğimizin çıktısı:
Projenize böyle bir animasyon eklemek istediğinizde özel bir kütüphane yüklemenize gerek yoktur. Çünkü kullanacağım ValueAnimator animasyon sınıfı android’in temel sınıflarından biridir.
ValueAnimator Sınıfı Ne İşe Yarar?
Android’de ValueAnimator‘ı kullanmak, animasyon eklemenin en basit yollarından biridir. ValueAnimator ile bir arayüz elementinin genişliğini, yüksekliğini, x ve y koordinatlarını güncelleyebilir. Hatta arka planını değiştirebilirsiniz.
Örneğimizde ise ValueAnimator sınıfının ofInt ve addUpdateListener metotlarından faydalanacağım.
ValueAnimator sınıfının ofInt metodu
ofInt metodu, int değerleri arasında animasyon uygulayan bir ValueAnimator oluşturur. Örnek projede ise ofInt metoduna int değer olarak animasyon uygulanacak yazının yükseklik değerini verdim. subtitleHeight değeri 100 olsun. 100’den 0 değerine kadar yükselik azalarak metnin görünürlüğün kapatmak istediğimiz için ofInt kullanıyoruz. ofInt’den dönen değeride addUpdateListener metodu ile güncellemeyi unutmamalıyız. (Projede oluşturduğum hideSubtitle metodu)
Not: tvSubtitle.height değeri oluşturduğum showSubtitle metodundaki View measure metodu ile elde edilmiştir.
Daha detaylı açıklamaları kodlar arasında bulabilirsiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
import android.animation.ValueAnimator import android.content.res.Resources import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.TypedValue import android.view.View import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.animation.doOnEnd import androidx.core.view.isVisible class MainActivity : AppCompatActivity() { private lateinit var tvSubtitle: TextView private lateinit var clContainer: ConstraintLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val ivExpand: View = findViewById(R.id.iv_expand) tvSubtitle = findViewById(R.id.tv_subtitle) clContainer = findViewById(R.id.cl_container) //dropdown icon tıkladığında... ivExpand.setOnClickListener { if (!tvSubtitle.isVisible) { showSubtitle() //dropdown icon 180 derece döndürüyoruz ivExpand.rotation = 180f } else { hideSubtitle() //dropdown iconu ilk haline döndürüyoruz ivExpand.rotation = 0f } } } private fun hideSubtitle() { //yazı alanının kullandığı yükselik değerini alalım val subtitleHeight = tvSubtitle.height //makale de bu bölümün açıklamasını bulabilirsiniz val heightAnimator = ValueAnimator.ofInt(subtitleHeight, 0) heightAnimator.addUpdateListener { tvSubtitle.updateHeight(it.animatedValue as Int) } heightAnimator.doOnEnd { tvSubtitle.isVisible = false } heightAnimator.start() } private fun showSubtitle() { tvSubtitle.updateHeight(ConstraintLayout.LayoutParams.WRAP_CONTENT) //View measure metodu sayesinde tvSubtitle adlı Textview'in yükseklik değeri buluyoruz val totalMarginForSubtitle = 2 * 16.toPx() tvSubtitle.measure( View.MeasureSpec.makeMeasureSpec( clContainer.width - totalMarginForSubtitle, View.MeasureSpec.EXACTLY ), View.MeasureSpec.UNSPECIFIED ) val subtitleHeight = tvSubtitle.measuredHeight tvSubtitle.height = 0 tvSubtitle.isVisible = true //Textviewdeki içerik animasyonlu görünür hale getiriyoruz val heightAnimator = ValueAnimator.ofInt(0, subtitleHeight) heightAnimator.addUpdateListener { tvSubtitle.height = it.animatedValue as Int } heightAnimator.start() } fun View.updateHeight(newHeight: Int) { layoutParams = layoutParams.apply { height = newHeight } } fun Int.toPx() = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), Resources.getSystem().displayMetrics ).toInt() } |
Son olarak projemizin arayüz kodunu paylaşıyorum. Arayüz kodlamasında kullanılan resim vb dosyalara ve tüm kodlara github linkinden ulaşabilirsiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/cl_container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:id="@+id/iv_header" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/arisutu" app:layout_constraintBottom_toTopOf="@+id/tv_title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="MissingConstraints" /> <TextView android:id="@+id/tv_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:text="Arı sütü nedir?" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@id/tv_subtitle" app:layout_constraintEnd_toStartOf="@id/iv_expand" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/iv_header" app:layout_constraintVertical_chainStyle="packed" /> <ImageView android:id="@+id/iv_expand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="16dp" android:background="@drawable/expand" app:layout_constraintBottom_toBottomOf="@id/tv_title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/tv_title" /> <TextView android:id="@+id/tv_subtitle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:text="Arı sütü, 5-15 günlük işçi arıların yutak üstü salgı bezlerinden salgıladıkları bir maddedir. Jel halinde akıcı kıvamda, kremsi-beyaz renktedir. Tadı ekşi ve kokusu keskin fenolik yapıdadır.Arı sütü ana arının ve larvaların besini olup, besin değeri oldukça yüksektir. Ana arı ve işçi arılar yumurtadan çıktıklarında aynı genetik yapıya sahip olmalarına rağmen, larva döneminde 6 gün süreyle farklı oranda arı sütüyle beslenmeleri ana arılarının biyolojik yapılarının farklılaşmasına neden olmaktadır, işçi arılarda ise arı sütü ile beslenme süresi 3 gün ile sınırlıdır ve daha düşük kalitede bir arı sütüyle beslenmektedirler." android:visibility="gone" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_title" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Projenin tüm kodlarına github linkinden ulaşabilirsiniz.
Kaynak
https://proandroiddev.com/textview-reveal-animation-on-android-19b865bc0169
https://developer.android.com/reference/android/animation/ValueAnimator