android / views-widgets-samples

Multiple samples showing the best practices in views-widgets on Android.
Apache License 2.0
5.03k stars 3.01k forks source link

ViewPager2 with a Preview of Next/Prev Page bug #198

Open dyl169 opened 3 years ago

dyl169 commented 3 years ago
package androidx.viewpager2.integration.testapp

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import kotlinx.android.synthetic.main.activity_viewpager2.*
import kotlinx.android.synthetic.main.item_preview_pages.view.*

class PreviewPagesActivity : FragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_viewpager2)
        findViewById<ViewPager2>(R.id.view_pager).apply {
            // Set offscreen page limit to at least 1, so adjacent pages are always laid out
            offscreenPageLimit = 1
            val recyclerView = getChildAt(0) as RecyclerView
            recyclerView.apply {
                val padding = resources.getDimensionPixelOffset(R.dimen.halfPageMargin) +
                        resources.getDimensionPixelOffset(R.dimen.peekOffset)
                // setting padding on inner RecyclerView puts overscroll effect in the right place
                // TODO: expose in later versions not to rely on getChildAt(0) which might break
                setPadding(padding, 0, padding, 0)
                clipToPadding = false
            }
            adapter = Adapter()
        }
        view_pager.setPageTransformer(mAnimator)

        btn_set.setOnClickListener { view_pager.adapter!!.notifyDataSetChanged() }
        btn_set1.setOnClickListener { view_pager.currentItem = 2 }
    }

    private val mAnimator = ViewPager2.PageTransformer { page, position ->
        val absPos = Math.abs(position)
        val MAX_SCALE = 1.0f
        val MIN_SCALE = 0.8f
        page.apply {
            val tempScale = if (position < 0) 1 + position else 1 - position

            val slope: Float = (MAX_SCALE - MIN_SCALE) / 1

            val scaleValue: Float = MIN_SCALE + tempScale * slope
            page.scaleY = scaleValue
        }
    }

    class ViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.item_preview_pages, parent, false)
    )

    class Adapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
        override fun getItemCount(): Int {
            return 10
        }

        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): RecyclerView.ViewHolder {
            return ViewHolder(parent)
        }

        @SuppressLint("SetTextI18n")
        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            holder.itemView.tag = position
            holder.itemView.tv_index.text = "" + position
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#AA0C2962"
        android:overScrollMode="never" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="20dp">

        <Button
            android:id="@+id/btn_set"
            style="@style/Widget.AppCompat.Button.Borderless"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:layout_weight="1"
            android:background="@color/blue_100"
            android:text="设置" />

        <Button
            android:id="@+id/btn_set1"
            style="@style/Widget.AppCompat.Button.Borderless"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:layout_marginLeft="40dp"
            android:layout_weight="1"
            android:background="@color/blue_100"
            android:text="随机移动" />
    </LinearLayout>

</LinearLayout>

After adding the Scale change of PageTransformer to viewPager, the following bug appears when notifyDataSetChanged is executed on Adapter

correct: image bug: image