基于上篇(添加了页面指示器): https://blog.csdn.net/whjk20/article/details/107338023
指示器的代码抽离出来,通过自定义VIEW实现, 重复部分不再写
1. 继承ConstraintLayout, 自定义指示器VIEW
class ViewPagerIndicator @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val defaultCircleResId = R.drawable.indicator_dot_off
private val selectedCircleResId = R.drawable.indicator_dot_on
private var imageDots = mutableListOf<ImageView>()
fun updateIndicatorDots(pageCount: Int, position: Int, horizontalMargin: Int) {
makeIndicatorDots(pageCount, horizontalMargin)
addIndicatorDotsToView()
applyConstraintSet()
updateSelectedDot(position)
}
fun updateSelectedDot(position: Int) {
for (index in 0 until imageDots.size) {
if (index == position) {
//TODO - setImageResource 无效?
//indicatorDatas[index].setImageResource(R.drawable.indicator_dot_on)
imageDots[index].setBackgroundResource(selectedCircleResId)
} else {
//indicatorDatas[index].setImageResource(R.drawable.indicator_dot_off)
imageDots[index].setBackgroundResource(defaultCircleResId)
}
}
}
private fun applyConstraintSet() {
var cs: ConstraintSet = ConstraintSet()
cs.clone(this)
var prevItemId = -1
for (index in 0 until imageDots.size) {
if (prevItemId == -1) {
prevItemId = ConstraintSet.PARENT_ID
cs.setHorizontalChainStyle(imageDots[index].id, ConstraintSet.CHAIN_PACKED)
cs.connect(
imageDots[index].id,
ConstraintSet.START, prevItemId,
ConstraintSet.START
)
} else {
cs.connect(imageDots[index].id, ConstraintSet.START, prevItemId, ConstraintSet.END)
cs.connect(prevItemId, ConstraintSet.END, imageDots[index].id, ConstraintSet.START)
}
prevItemId = imageDots[index].id
if (index == imageDots.size - 1) {
cs.connect(
imageDots[index].id,
ConstraintSet.END,
ConstraintSet.PARENT_ID,
ConstraintSet.END
)
}
}
cs.applyTo(this)
}
// 添加indicator 到布局中
private fun addIndicatorDotsToView() {
for (index in 0 until imageDots.size) {
addView(imageDots[index])
}
}
private fun makeIndicatorDots(count: Int, horizontalMargin: Int) {
for (index in 0 until count) {
imageDots.add(ImageView(context).also {
it.id = View.generateViewId()
it.setPadding(horizontalMargin, horizontalMargin, horizontalMargin, 0)
})
}
}
}
跟之前的代码没有什么特别,只是公开了两个接口供调用
fun updateIndicatorDots(pageCount: Int, position: Int, horizontalMargin: Int)
fun updateSelectedDot(position: Int)
2. MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var context: Context
private lateinit var viewPagerAdapter: ViewPagerAdapter
private var datas = mutableListOf<UserData>()
companion object{
const val TAG = "MainActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
context = this
initDatas()
showViewPager()
addListener()
view_pager_indicator.updateIndicatorDots(datas.size, 0, context.resources.getDimensionPixelOffset(R.dimen.indicator_dot_padding))
}
private fun initDatas() {
for (index in 0 until USER_NAMES.size) {
datas.add(
index,
UserData(
context.getString(USER_NAMES[index]), PIC_IDS[index]
)
)
}
}
private fun showViewPager() {
viewPagerAdapter = ViewPagerAdapter(context, datas)
view_pager.adapter = viewPagerAdapter
// 设置缓存数量, 例如设置为3, 则首次进入加载并显示了数据第一项的,同时缓存第2~4项
// 当滑动到第二页时,缓存第5项的 (销毁时机不确定destroyItem)
view_pager.offscreenPageLimit = 3
}
private fun addListener() {
view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
}
override fun onPageSelected(position: Int) {
view_pager_indicator.updateSelectedDot(position)
}
})
}
}
这里仅做数据初始化 、创建和设置ViewPager适配器、初始化指示器控件、监听界面滑动并更改当前指示器