今天给大家实现一个自定义的卡片切换效果。
gallery
工程结构非常简单,就以下三个类:
一. 页面相关TestGalleryActivity
package com.openld.seniorui.testgallery
import android.os.Bundle
import android.os.Message
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.openld.seniorui.R
import java.util.*
class TestGalleryActivity : AppCompatActivity() {
private val TAG = "Gallery"
private var mCurrentIndex = 0
private lateinit var mGallery: ViewPager
private val mFruitList = mutableListOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test_gallery)
initData()
initWidgets()
addListeners()
}
private fun initData() {
mFruitList.add(R.drawable.fruit_image1)
mFruitList.add(R.drawable.fruit_image2)
mFruitList.add(R.drawable.fruit_image3)
mFruitList.add(R.drawable.fruit_image4)
mFruitList.add(R.drawable.fruit_image5)
mFruitList.add(R.drawable.fruit_image6)
mFruitList.add(R.drawable.fruit_image7)
mFruitList.add(R.drawable.fruit_image8)
mFruitList.add(R.drawable.fruit_image9)
mFruitList.add(R.drawable.fruit_image10)
mFruitList.add(R.drawable.fruit_image11)
mFruitList.add(R.drawable.fruit_image12)
mFruitList.add(R.drawable.fruit_image13)
mFruitList.add(R.drawable.fruit_image14)
mFruitList.add(R.drawable.fruit_image15)
mFruitList.add(R.drawable.fruit_image16)
mFruitList.add(R.drawable.fruit_image17)
}
private fun addListeners() {
mGallery.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
Log.d(TAG, ">>> $position")
mCurrentIndex = position
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {
}
})
}
private fun initWidgets() {
Message.obtain()
mGallery = findViewById(R.id.gallery)
val adapter = GalleryAdapter(this, mFruitList)
mGallery.offscreenPageLimit = mFruitList.size
mGallery.adapter = adapter
mGallery.currentItem = mFruitList.size - 1
mGallery.setPageTransformer(false, GalleryTransformer())
// 滑到第一个
scrollToFirst()
// 训话滑动轮播
loopScroll()
}
private fun loopScroll() {
// 轮播
mGallery.postDelayed({
val timer = Timer()
timer.schedule(object : TimerTask() {
override fun run() {
if (mCurrentIndex == mFruitList.size) {
mCurrentIndex = 0
}
mGallery.currentItem = mCurrentIndex++
}
}, 0, 2000)
}, 2200)
}
private fun scrollToFirst() {
// 这鬼滑动速度不知道怎么控制
mGallery.postDelayed({
mGallery.setCurrentItem(0, true)
}, 200)
}
}
页面布局activity_test_gallery.xml
页面中的图片资源自己替换下好了
二.适配器GalleryAdapter
package com.openld.seniorui.testgallery import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.annotation.NonNull import androidx.appcompat.widget.AppCompatImageView import androidx.viewpager.widget.PagerAdapter import com.openld.seniorui.R class GalleryAdapter(@NonNull context: Context, @NonNull fruitList: List) : PagerAdapter() { private val mContext = context private var mFruitList: List = fruitList override fun getCount(): Int { return mFruitList.size } override fun isViewFromObject(view: View, `object`: Any): Boolean { return view == `object` } override fun instantiateItem(container: ViewGroup, position: Int): Any { return LayoutInflater.from(mContext).inflate(R.layout.item_gallery, container, false) .apply { val imgFruit: AppCompatImageView = findViewById(R.id.img_fruit) imgFruit.setImageResource(mFruitList[position]) imgFruit.setOnClickListener { Toast.makeText(mContext, "点击了第${position}个图片", Toast.LENGTH_SHORT).show() } tag = "gallery_item_$position" container.addView(this) } } override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { container.removeView(`object` as View) } }
适配器条目布局item_gallery.xml
用到的图片资源自己换一下好了
三.转换器GalleryTransformer
控制滑动时候的各种属性变化,达到自定义滑动切换时候的炫酷效果。
package com.openld.seniorui.testgallery
import android.view.View
import androidx.viewpager.widget.ViewPager
class GalleryTransformer : ViewPager.PageTransformer {
private val MIN_SCALE = 0.5F
override fun transformPage(page: View, position: Float) {
if (position < 0F) {
page.scaleX = MIN_SCALE * position + 1.5F
page.scaleY = MIN_SCALE * position + 1.5F
page.alpha = MIN_SCALE * position + 1
// page.rotationY = 30F * position
page.rotation = 30 * position
} else {
page.scaleX = -MIN_SCALE * position + 1.5F
page.scaleY = -MIN_SCALE * position + 1.5F
page.alpha = -MIN_SCALE * position + 1
// page.rotationY = 30F * position
page.rotation = 30 * position
}
page.elevation = page.scaleX
}
}
这里效果的关键就是这个GalleryTransformer类,不明白原理的可以看下ViewPager.PageTransformer的相关源码或者解释。
就是page滑到中间的时候position为0,page在左侧时position取值区间为(-1, 0),page在右侧时position取值区间为(0, 1),根据这个再结合一些诸如alpha、scaleX、scaleY、rotation等属性的设置就能实现你要的切换效果啦。



