• Above,Tianjin Metro APPtheBannerIt is also the effect to be achieved in this paper

How to use ViewPager2

  • (1) inappUnder thebuild.gradleAdd the following dependencies to the file
Implementation "androidx viewpager2: viewpager2:1.0.0."Copy the code
  • ② After synchronization, it can be used in the layout
<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/bannerVp"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    />
Copy the code
  • As can be seen from the figureitemThe layout needs rounded corners. There are many implementation schemes. Here I choose to use the official oneShapeableImageViewTo implement rounded corners, I need to write onestyle
<style name="BannerStyle">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">@dimen/_10dp</item>
</style>
Copy the code

The reference code in the layout is as follows

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/banner_image"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:scaleType="fitXY"
    app:shapeAppearance="@style/BannerStyle"
/>
Copy the code
  • We all know thatViewPager2Adapter andRecyclerViewI won’t post the code here
  • ⑤ Finally we giveViewPager2On the setadapterCan be

2. Infinite sliding of the rotation map

  • The first digit of the data sourceaddLast picture
val newList = arrayListOf<String>()
newList.add(pic[pic.size-1])
Copy the code
  • The last bit adds the first diagram
for (item in pic) {
    newList.add(item)
}
newList.add(pic[0])
Copy the code
  • The processing of ViewPager2 when it slides to the 0th and last bits is as follows
location To deal with
currentPosition == 0 setCurrentItem(adapter.itemCount - 2, false)
currentPosition == adapter.itemCount - 1 setCurrentItem(1, false)
  • ViewPager2Add the slide listener code below

The key point is the onPageScrollStateChanged method

bannerVp.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { currentPosition = position } override fun onPageScrollStateChanged(state: Int) {// Only in idle state, If (state == viewPager2. SCROLL_STATE_IDLE) {if (currentPosition == 0) { bannerVp.setCurrentItem(adapter.itemCount - 2, false) } else if (currentPosition == adapter.itemCount - 1) { bannerVp.setCurrentItem(1, false) } } } })Copy the code

Three, automatic sliding

  • So this is usingviewthepostDelayedMethod to implement
bannerVp.postDelayed(mLooper,1000)
Copy the code
  • mLooperI defined itRunnableAnd we’ll talk about why later
private val mLooper = object : Runnable {
    override fun run() {
        bannerVp.currentItem = ++bannerVp.currentItem
        bannerVp.postDelayed(this,1000)
    }
}
Copy the code
  • Swiping works, but start-stop timing is also important

So onWindowFocusChanged is used here because it notifies us when the window loses and gains focus

override fun onWindowFocusChanged(hasFocus: Boolean) {super. OnWindowFocusChanged (hasFocus) if (hasFocus) {bannerVp. PostDelayed (mLooper, 1000)} else {/ / lost focus when removed bannerVp.removeCallbacks(mLooper) } }Copy the code
  • That’s whyremoveCallbacksYou have to take itmLooperPass it in. So let’s define it separately

Touch pause scroll

  • We know touch callssetOnTouchListenerB: Yes, but here you areViewPager2You’ll find it doesn’t work when you use it.
  • ViewPager2Is a view group, not calledsetOnTouchListenerbecauserecyclerviewIntercept the event and call it firstonTouchEvent
  • bannerVp.getChildAt(0)Set it to listen
bannerVp.getChildAt(0).setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { bannerVp.removeCallbacks(counter) } MotionEvent.ACTION_UP ->  { bannerVp.postDelayed(counter,1000) } } return@setOnTouchListener false }Copy the code

The last

Writing is not easy, if you have a drop of help or inspiration, thank you for your support, if you have a question, also welcome to leave a message!