【问题标题】:Custom vertical viewpager not work with onClick listener on a child view自定义垂直视图分页器不适用于子视图上的 onClick 侦听器
【发布时间】:2017-11-15 16:57:29
【问题描述】:

我从这里 (Android: Vertical ViewPager) 创建了这个自定义 ViewPager:

class VerticalViewPager : ViewPager {

@JvmOverloads
constructor(
        context: Context,
        attrs: AttributeSet? = null)
        : super(context, attrs){
    setPageTransformer(false, DefaultTransformer())
    overScrollMode = OVER_SCROLL_NEVER
}

override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
    val intercepted = super.onInterceptTouchEvent(swapXY(ev))
    swapXY(ev) // return touch coordinates to original reference frame for any child views
    return intercepted
}

override fun onTouchEvent(ev: MotionEvent?): Boolean {
    return super.onTouchEvent(ev)
}

/**
 * Swaps the X and Y coordinates of your touch event.
 */
private fun swapXY(ev: MotionEvent): MotionEvent {
    val width = width.toFloat()
    val height = height.toFloat()

    val newX = ev.y / height * width
    val newY = ev.x / width * height

    ev.setLocation(newX, newY)

    return ev
}

private class VerticalPageTransformer : ViewPager.PageTransformer{
    override fun transformPage(view: View, position: Float) {
        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.alpha = 0f

        } else if (position <= 1) { // [-1,1]
            view.alpha = 1f

            // Counteract the default slide transition
            view.translationX = view.getWidth() * -position

            //set Y position to swipe in from top
            val yPosition = position * view.getHeight()
            view.translationY = yPosition

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.alpha = 0f
        }
    }

}

}

我使用在每个页面内加载 ImageView 的适配器。这个 ImageView 有一个 onClickListener。

open class VerticalViewPagerAdapter(var mContext: Context, val photos : RealmList<ProfilePhoto>?, onPhotoClick: OnPhotoClick?) : PagerAdapter() {

var mLayoutInflater : LayoutInflater? = null
val onPhotoListener = onPhotoClick

init {
    mLayoutInflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
}

override fun getCount(): Int {
    return photos?.size!!
}

override fun isViewFromObject(view: View, `object`: Any): Boolean {
    return view === `object` as FrameLayout
}

override fun instantiateItem(container: ViewGroup, position: Int): Any {
    val itemView = mLayoutInflater?.inflate(R.layout.view_image_profile_viewpager_item, container, false)

    val imageView = itemView?.findViewById(R.id.profileImageItemIv) as ImageView

    imageView.setOnClickListener{
        onPhotoListener?.onPhotoClick(position)
    }

    imageView.loadUrlImage(photos!![position]?.photo)

    container.addView(itemView)

    return itemView
}

override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
    container.removeView(`object` as FrameLayout)
}
}

如果 ImageView 具有此侦听器,则自定义 viewpager 上的滑动不起作用。如果我删除监听器,工作正常。

有人知道可能是什么问题吗?

【问题讨论】:

    标签: android android-viewpager kotlin android-pagetransformer


    【解决方案1】:

    最后我解决了这个问题。如果用户只点击 viewpager 而不是交换,我将向 onInterceptTouchEvent 添加逻辑以释放 onTouch 事件。这是最终代码:

    class VerticalViewPager : ViewPager {
    
    var originalPosY = 0
    
    @JvmOverloads
    constructor(
            context: Context,
            attrs: AttributeSet? = null)
            : super(context, attrs){
        setPageTransformer(false, DefaultTransformer())
    }
    
    private fun swapTouchEvent(event: MotionEvent): MotionEvent {
        val width = width.toFloat()
        val height = height.toFloat()
    
        val swappedX = event.y / height * width
        val swappedY = event.x / width * height
    
        event.setLocation(swappedX, swappedY)
    
        return event
    }
    
    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
    
        var y : Int = event.rawY.toInt()
    
        return when (event.action) {
    
            MotionEvent.ACTION_DOWN -> {
                originalPosY = y
                val intercept = super.onInterceptTouchEvent(swapTouchEvent(event))
                swapTouchEvent(event)
                false
            }
    
            MotionEvent.ACTION_MOVE -> {
    
                val intercept = super.onInterceptTouchEvent(swapTouchEvent(event))
                val i = swapTouchEvent(event)
                true
    
            }
    
            MotionEvent.ACTION_UP -> {
    
                if (Math.abs(originalPosY - y) > 10) {
                    super.onInterceptTouchEvent(swapTouchEvent(event))
                    val i = swapTouchEvent(event)
                    true
                }else
                    false
            }
    
            else -> super.onInterceptTouchEvent(swapTouchEvent(event))
    
        }
    }
    
    override fun onTouchEvent(event: MotionEvent): Boolean = super.onTouchEvent(swapTouchEvent(event))
    }
    

    结果并不完全符合我的要求。如果有人可以改进它,将受到欢迎

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多