Kullanıcı deneyimini arttıran elementler ile etkileşimli kullanıcı arayüz tasarlamak projenin yaşam döngüsü için çok önemlidir.
Bu makale Kotlin dili ile Android Viewpager2 widget’ına Carousel efektini ekleyerek slider yapımını örnekleyecektir.
Carousel efekti ile yapılan makale resim ve başlığının içerdiği slider örnek görüntüsü;
Proje kodlarına github linkinden ulaşabilirsiniz.
1-Proje Ayarları
Android Studio Ide ile oluşturduğum projemin app dizinin altındaki build.gradle dosyasını açıyoruz. Dependencies kod bloklarının arasına aşağıdaki kodları yerleştirerek Viewpager2 kütüphanesini yüklüyoruz.
1 |
implementation 'androidx.viewpager2:viewpager2:1.0.0' |
2- Adapter Oluşturma
Custom Listview mantığında olduğu gibi burada da bir Adapter sınıfı oluşturmamız gerekiyor. Adapter sınıfında bir tane item yapısında neler olacağı belirlenir. İtem’da nasıl bir arayüz olacağını tanımlamak için item.xml oluşturalım. Item köşelerinin yuvarlak gözükmesi drawable dizinin içine card_background xml oluşturalım. Bunu item.xml’de kullanacağız.
1 2 3 4 5 6 7 8 |
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:width="3dp" android:color="@android:color/white" /> <solid android:color="@color/colorPrimary" /> <corners android:radius="12dp" /> </shape> |
item.xml
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 |
<?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:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/card_background" android:elevation="8dp"> <ImageView android:id="@+id/imageView" android:layout_width="800px" android:layout_height="401px" android:layout_marginStart="20dp" android:layout_marginTop="20dp" android:layout_marginEnd="20dp" app:layout_constraintBottom_toTopOf="@+id/textview" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:srcCompat="@tools:sample/backgrounds/scenic" /> <TextView android:id="@+id/textview" android:layout_width="0dp" android:layout_height="0dp" android:gravity="center" android:padding="20dp" android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sit amet lectus a mi lobortis iaculis. Mauris odio tortor, accumsan vel gravida sit amet, malesuada a tortor. Cras mattis augue eget dolor vestibulum, id euismod diam rutrum." android:textAlignment="center" android:textColor="@android:color/black" android:textSize="19sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView" /> </androidx.constraintlayout.widget.ConstraintLayout> |
CarouselRVAdapter adında bir sınıf oluşturalım. Bu adapter sınıfında MainActivity sınıfından gelecek olan başlık ve resim değerlerini arayüze dinamik olarak nasıl yerleştireceğimizi göreceksiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import android.view.* import android.widget.* import androidx.recyclerview.widget.RecyclerView class CarouselRVAdapter(private val carouselDataListTitle: ArrayList<String>,private val carouselDataListImage: ArrayList<Int>) : RecyclerView.Adapter<CarouselRVAdapter.CarouselItemViewHolder>() { class CarouselItemViewHolder(view: View) : RecyclerView.ViewHolder(view) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CarouselItemViewHolder { val viewHolder = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false) return CarouselItemViewHolder(viewHolder) } override fun onBindViewHolder(holder: CarouselItemViewHolder, position: Int) { val image=holder.itemView.findViewById<ImageView>(R.id.imageView) image.setImageResource(carouselDataListImage[position]) val textView = holder.itemView.findViewById<TextView>(R.id.textview) textView.text = carouselDataListTitle[position] } override fun getItemCount(): Int { return carouselDataListTitle.size } } |
3-Carousel Efektini Viewpager2 Ekleme
İlk önce Xml dosyamızda Viewpager2 widget’ı ekleyelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?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:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimaryDark" android:clipChildren="false" android:clipToPadding="false" tools:context=".MainActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="280dp" android:layout_height="260dp" android:layout_marginTop="171dp" android:layout_marginBottom="300dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.496" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
MainActivity sınıfımızda üstteki layout xml kullanacağız. Bu sınıfta ViewPager2 widget’ına Carousel efektini ekleyebilmek için apply fonksiyonunu kullandım. Fonksiyonda kullandığım clipChildren, clipToPadding özelliklerinin detaylı açıklamasını Google dokümantasyonundan erişebilirsiniz.
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 |
import android.app.Activity import android.content.res.Resources import android.os.Bundle import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.* import kotlin.math.abs class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val viewPager = findViewById<ViewPager2>(R.id.view_pager) //Carousel Efektini Viewpager2 Ekleme viewPager.apply { clipChildren = false // Sol ve sağ item'ları sayfada gösterme durumu clipToPadding = false // viewpager item görüntülerken padding kullanma durumu offscreenPageLimit = 2 (getChildAt(0) as RecyclerView).overScrollMode = RecyclerView.OVER_SCROLL_NEVER // Scroll effect silme } //Makale başlıkları val articleTitle = arrayListOf( "Compose Tasarım Araç ve Özellikleri", "Apk Uygulama İçi Güncelleme", "Android Compose’da Lazy Layout Kullanımı", "“Insecure Data Storage” Güvenlik Zafiyetleri", "Android View ile Compose Birlikte Kullanımı" ) //Makale resimleri val articleImage=arrayListOf(R.drawable.composetooling,R.drawable.in_app_update,R.drawable.lazylayouts,R.drawable.android_security,R.drawable.interoperability_with_compose) viewPager.adapter = CarouselRVAdapter(articleTitle,articleImage) //Item'lar arasına biraz boşluk eklemek için MarginPageTransformer kullanalım... val compositePageTransformer = CompositePageTransformer() compositePageTransformer.addTransformer(MarginPageTransformer((40 * Resources.getSystem().displayMetrics.density).toInt())) compositePageTransformer.addTransformer { page, position -> val r = 1 - abs(position) page.scaleY = (0.80f + r * 0.20f) } viewPager.setPageTransformer(compositePageTransformer) } } |
Proje kodlarına github linkinden ulaşabilirsiniz.
Kaynaklar
1- https://developer.android.com/reference/android/view/ViewGroup.html#setClipChildren(boolean)