解决ViewPager设置切换动画PageTransformer后子页无法触摸的问题

通过ViewPager.setPageTransformer()方法可以设置切换动画,但是如果ViewPager的子页中要处理触摸事件,如浏览图片时对图片放大缩小,ViewPager切换子页后,不能处理触摸事件,似乎子页里面的变的不可点击。尝试了很多中Google上的方法,仍不能解决问题。其实这个是android4.1+版本上的bug,在调用了setPageTransformer()方法后,切换子页后,当前最上面的View并不是眼睛所看的,而是另一个隐藏的子页,该隐藏的子页消费了触摸事件。尝试了把当前子页“放到最上面”,view.bringToFornt(),甚至把其他看不见的子页都设置为隐藏,otherView.setVisibility(View.GONE),当前子页仍然不能处理触摸事件。


最后查看了viewPager的源码,发现执行切换动画的代码在onPageScrolled()方法内:

if(this.mPageTransformer != null) {
            scrollX = this.getScrollX();
            childCount = this.getChildCount();

            for(i = 0; i < childCount; ++i) {
                View var15 = this.getChildAt(i);
                ViewPager.LayoutParams var16 = (ViewPager.LayoutParams)var15.getLayoutParams();
                if(!var16.isDecor) {
                    float var17 = (float)(var15.getLeft() - scrollX) / (float)this.getClientWidth();
                    this.mPageTransformer.transformPage(var15, var17);
                }
            }
        }

其中的mPageTransformer就是setPageTransformer()传进来的参数。于是,解决的方法便出来了:

public class SimpleViewPager extends ViewPager {

    private PageTransformer mPageTransformer;

    public SimpleViewPager(Context context) {
        this(context, null);
    }

    public SimpleViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * android4.1+设置PageTransformer会使ViewPager的子页里面的触摸事件异常
     * (当前看到的子页并非在最上面,所以触摸事件被隐藏在其上面的View给消费了)
     * 所以结合setPageTransformer(),在onPageScrolled()里“手动”调用切换页面的动画
     *
     * @param position
     * @param offset
     * @param offsetPixels
     */
    @Override
    protected void onPageScrolled(int position, float offset, int offsetPixels) {
        super.onPageScrolled(position, offset, offsetPixels);
        // 下面的源码来自super.onPageScrolled()
        int scrollX;
        int childCount;
        int i;
        if (this.mPageTransformer != null) {
            scrollX = this.getScrollX();
            childCount = this.getChildCount();

            for (i = 0; i < childCount; ++i) {
                View var15 = this.getChildAt(i);
                ViewPager.LayoutParams var16 = (ViewPager.LayoutParams) var15.getLayoutParams();
                if (!var16.isDecor) {
                    float var17 = (float) (var15.getLeft() - scrollX) / (float) this.getClientWidth();
                    this.mPageTransformer.transformPage(var15, var17);
                }
            }
        }
    }

    private int getClientWidth() {
        return this.getMeasuredWidth() - this.getPaddingLeft() - this.getPaddingRight();
    }

    /**
     * 覆盖该方法,不设置PageTransformer,以成员变量的形式保存PageTransformer
     *
     * @param reverseDrawingOrder
     * @param transformer
     */
    @Override
    public void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) {
        super.setPageTransformer(reverseDrawingOrder, null);
        mPageTransformer = transformer;
    }

}


原理很简单,既然是因为设置了PageTransformer才导致子页的触摸事件异常,那么就不设置该属性,通过间接的方式执行切换动画。上面的类继承了ViewPager,覆盖了setPageTransformer()和onPageScrolled(),保存传进来的PageTransformer对象,父类ViewPager的mPageTransformer实际上为空,在onPageScrolled()方法中“手动执行”切换动画。


完整的代码放在了github上:https://github.com/1993hzw/Androids

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值