android ViewPager2
本文介绍了Android ViewPager2的使用指南:1) 基础用法包括添加依赖、布局配置;2) 两种适配器实现方式(FragmentStateAdapter和RecyclerView.Adapter);3) 高级功能如页面间距设置、TabLayout集成、动态增删页面;4) 常见问题解决方案;5) 完整示例代码展示ViewPager2与Fragment、TabLayout的结合使用。View
以下是关于 ViewPager2 的详细使用指南,包含核心功能、代码示例及最佳实践:
一、ViewPager2 基础用法
1. 添加依赖
在 build.gradle中添加:
dependencies {
implementation 'androidx.viewpager2:viewpager2:1.1.0'
}
2. 布局文件中添加 ViewPager2
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
二、创建适配器
(1) 继承 FragmentStateAdapter(推荐用于 Fragment)
class MyPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
private val items = listOf("Page 1", "Page 2", "Page 3")
override fun getItemCount(): Int = items.size
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> PageFragment.newInstance(items[0])
1 -> PageFragment.newInstance(items[1])
else -> PageFragment.newInstance(items[2])
}
}
}
(2) 继承 RecyclerView.Adapter(自定义 View)
class MyViewPagerAdapter(private val items: List<String>) : RecyclerView.Adapter<MyViewPagerAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val textView: TextView = itemView.findViewById(R.id.item_text)
fun bind(item: String) {
textView.text = item
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_page, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
override fun getItemCount(): Int = items.size
}
三、绑定适配器与设置监听
在 Activity/Fragment 中
class MainActivity : AppCompatActivity() {
private lateinit var viewPager: ViewPager2
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewPager = findViewById(R.id.viewPager)
// 使用 Fragment 适配器
val adapter = MyPagerAdapter(this)
viewPager.adapter = adapter
// 或使用自定义 View 适配器
// val adapter = MyViewPagerAdapter(listOf("A", "B", "C"))
// viewPager.adapter = adapter
// 监听页面切换
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
Toast.makeText(this@MainActivity, "当前页:$position", Toast.LENGTH_SHORT).show()
}
})
}
}
四、高级功能
1. 设置页面间距
// 在 Activity/Fragment 中
val pageMarginPx = resources.getDimensionPixelOffset(R.dimen.page_margin)
val offsetPx = resources.getDimensionPixelOffset(R.dimen.page_offset)
viewPager.setPageTransformer { page, position ->
val offset = position * -(2 * offsetPx + pageMarginPx)
page.translationX = offset.toFloat()
}
2. 与 TabLayout 结合
// 在 Activity/Fragment 中
val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = "Tab ${position + 1}"
}.attach()
3. 动态添加/删除页面
// 更新数据源
adapter.items.add("New Page")
adapter.notifyDataSetChanged()
// 删除页面
adapter.items.removeAt(0)
adapter.notifyItemRemoved(0)
五、常见问题解决
1. 页面闪烁或复用问题
-
原因:默认启用视图复用,可能导致动画异常。
-
解决:关闭视图复用:
viewPager.offscreenPageLimit = items.size // 保留所有页面
2. Fragment 状态丢失
-
原因:配置变更(如屏幕旋转)导致 Fragment 重建。
-
解决:在 Fragment 中使用
setRetainInstance(true)或通过 ViewModel 保存状态。
3. 与 RecyclerView 冲突
-
原因:同时使用 ViewPager2 和 RecyclerView 时滚动冲突。
-
解决:为 RecyclerView 添加嵌套滚动监听:
recyclerView.isNestedScrollingEnabled = false
六、完整示例代码
Activity
class ViewPager2DemoActivity : AppCompatActivity() {
private lateinit var viewPager: ViewPager2
private lateinit var adapter: MyPagerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_pager2_demo)
viewPager = findViewById(R.id.viewPager)
adapter = MyPagerAdapter(this)
viewPager.adapter = adapter
// 设置页面间距
val pageMargin = resources.getDimensionPixelSize(R.dimen.page_margin)
val offset = resources.getDimensionPixelSize(R.dimen.page_offset)
viewPager.setPageTransformer { page, position ->
val offsetPx = position * -(2 * offset + pageMargin)
page.translationX = offsetPx.toFloat()
}
// 绑定 TabLayout
val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = "Section $position"
}.attach()
}
}
适配器
class MyPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
override fun getItemCount(): Int = 3
override fun createFragment(position: Int): Fragment {
return ContentFragment.newInstance(position + 1)
}
}
Fragment
class ContentFragment : Fragment() {
companion object {
private const val ARG_PAGE = "ARG_PAGE"
fun newInstance(page: Int): ContentFragment {
return ContentFragment().apply {
arguments = Bundle().apply { putInt(ARG_PAGE, page) }
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = FragmentContentBinding.inflate(inflater, container, false)
val page = arguments?.getInt(ARG_PAGE) ?: 1
binding.textView.text = "Page $page"
return binding.root
}
}
七、总结
ViewPager2 的核心优势:
-
兼容性:基于 RecyclerView 实现,支持横向滑动和垂直滑动。
-
生命周期管理:自动处理 Fragment 的创建与销毁。
-
灵活性:支持自定义页面间距、动画和与 TabLayout 的无缝集成。
通过合理使用适配器和页面变换,可以轻松实现复杂的滑动交互场景(如引导页、轮播图、多屏切换)。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)