ViewPager2
viewPager2现在已经发布到1.0.0-beta04
,它相较于viewPager我认为比较重大的改善就是采用RecyclerView的Adapter,这使得它可以很方便的动态添加,移除,变更item,这在老版本的ViewPager中是比较麻烦的
使用
- 添加依赖
dependencies {
implementation "androidx.viewpager2:viewpager2:1.0.0-beta04"
}
- layout中添加
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- 添加具体的子layout布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvTitle"
android:textColor="@android:color/white"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
tools:text= "item"
android:textSize="32sp"
android:layout_height="wrap_content" />
</RelativeLayout>
- 为ViewPager2创建Adapter类,不同于ViewPager,我们可以使用RecyclerView.Adapter
class ViewPagerAdapter : RecyclerView.Adapter<PagerVH>() {
private val colors = intArrayOf(
android.R.color.black,
android.R.color.holo_red_light,
android.R.color.holo_blue_dark,
android.R.color.holo_purple
)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagerVH =
PagerVH(LayoutInflater.from(parent.context).inflate(R.layout.item_page, parent, false))
override fun getItemCount(): Int = colors.size
override fun onBindViewHolder(holder: PagerVH, position: Int) = holder.itemView.run {
tvTitle.text = "item $position"
container.setBackgroundResource(colors[position])
}
}
class PagerVH(itemView: View) : RecyclerView.ViewHolder(itemView)
将ViewPager2和adapter关联
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewPager2.adapter = ViewPagerAdapter()
}
}
看起来是不是非常简单,使用方法基本和RecyclerView相同
垂直滑动
如果之前在viewpager中使用垂直滑动只能够用第三方库,现在使用ViewPager2,我们可以很方便的切换滑动方向
viewPager2.orientation = ViewPager2.ORIENTATION_VERTICAL
使用FragmentStateAdapter
一样可以在ViewPager2中搭配fragments使用
- 首先,让我们创建一个fragment
class PagerFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.item_page, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
arguments?.let {
container.setBackgroundResource(it.getInt("color"))
tvTitle.text = "Item ${it.getInt("position")}"
}
}
}
- 然后创建一个Adapter
class ViewPagerFragmentStateAdapter(fm: FragmentManager) : FragmentStateAdapter(fm) {
private val colors = intArrayOf(
android.R.color.black,
android.R.color.holo_red_light,
android.R.color.holo_blue_dark,
android.R.color.holo_purple
)
override fun getItem(position: Int): Fragment = PagerFragment().apply {
arguments = bundleOf(
"color" to colors[position],
"position" to position
)
}
override fun getItemCount(): Int = colors.size
}
- 然后在Ativity中绑定
viewPager2.adapter = ViewPagerFragmentStateAdapter(supportFragmentManager)
OnPageChangeCallback
如果用之前的viewPager,如果我们要添加监听器,是这样的:
oldViewPager.addOnPageChangeListener(object:ViewPager.OnPageChangeListener{
override fun onPageScrollStateChanged(state: Int) {
// useless
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
// useless too
}
override fun onPageSelected(position: Int) {
// useful
}
})
不得不重写三个方法,而ViewPager2中,使用OnPageChangeCallback可以很方便的添加监听器
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
// No boilerplate, only useful
}
})
如何搭配tablayout
如果想要搭配tablayout,使用一个TabLayoutMediator类就可以了
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = Card.DECK[position].toString()
}.attach()
如何实现动态增添item
直接像RecyclerView一样动态添加,删除就可以了
adapter.notifyItemRangeInserted(position, count);
adapter.notifyItemRangeRemoved(position, count);
adapter.notifyItemMoved(fromPosition, toPosition);
adapter.notifyItemRangeChanged(position, count, payload);
item过渡动画:PageTransformer
当用户由一个item切换到另外一个item,可不可以有一些额外的动画呢。
基于ViewPager2.PagerTransformer可以实现这样的功能。
主要是创建一个类继承ViewPager2.PageTransformer,重写transformPage()
这个方法,这个方法有两个参数,一个是View, 一个position(float),具体的使用就是position参数代表了此刻用户滑动到了哪个位置,然后根据这个位置position去计算你想要让View所做的变换,这些变换包括但不限于
- rotation
- translationX/Y
- scaleX/Y
例如
private val mAnimator = ViewPager2.PageTransformer { page, position ->
val absPos = Math.abs(position)
page.apply {
rotation = if (rotateCheckBox.isChecked) position * 360 else 0f
translationY = if (translateY) absPos * 500f else 0f
translationX = if (translateX) absPos * 350f else 0f
if (scaleCheckBox.isChecked) {
val scale = if (absPos > 1) 0F else 1 - absPos
scaleX = scale
scaleY = scale
} else {
scaleX = 1f
scaleY = 1f
}
}
}
之后再和viewPager绑定
viewPager.setPageTransformer(mAnimator)
项目:
- google官方在github上有一个项目,展示了ViewPager2所能实现的一些相效果:google官方项目
参考文章: