pagetransformer 失效_软失效 硬失效 - CSDN
精华内容
参与话题
  • 通过阅读源码发现,ViewPager.setPageTransformer()方法可以设置切换动画,但是如果ViewPager的子页中要处理触摸事件,如浏览图片时对图片放大缩小,FragmentStateAdpter中要处理item的点击事件,View

    资料参考http://blog.csdn.net/u012964944/article/details/51065133,谢谢大神提供灵感。

    通过阅读源码发现,ViewPager.setPageTransformer()方法可以设置切换动画,但是如果ViewPager的子页中要处理触摸事件,如浏览图片时对图片放大缩小,FragmentStateAdpter中要处理item的点击事件,ViewPager切换子页后,不能处理触摸事件,或者触摸事件只有在切换后才响应,似乎子页里面的变的不可点击。尝试了很多中Google上的方法,包括修改setPageTransformer仍不能解决问题。

    其实这个是android4.1+版本上的bug,在调用了setPageTransformer()方法后,切换子页后,当前最上面的View并不是眼睛所看的,而是另一个隐藏的子页,该隐藏的子页消费了触摸事件。尝试了把当前子页“放到最上面”,view.bringToFornt(),甚至把其他看不见的子页都设置为隐藏,otherView.setVisibility(View.GONE),当前子页仍然不能处理触摸事件。


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


    1. if(this.mPageTransformer != null) {  
    2.             scrollX = this.getScrollX();  
    3.             childCount = this.getChildCount();  
    4.   
    5.             for(i = 0; i < childCount; ++i) {  
    6.                 View var15 = this.getChildAt(i);  
    7.                 ViewPager.LayoutParams var16 = (ViewPager.LayoutParams)var15.getLayoutParams();  
    8.                 if(!var16.isDecor) {  
    9.                     float var17 = (float)(var15.getLeft() - scrollX) / (float)this.getClientWidth();  
    10.                     this.mPageTransformer.transformPage(var15, var17);  
    11.                 }  
    12.             }  
    13.         }  
    1. public class SimpleViewPager extends ViewPager {  
    2.   
    3.     private PageTransformer mPageTransformer;  
    4.   
    5.     public SimpleViewPager(Context context) {  
    6.         this(context, null);  
    7.     }  
    8.   
    9.     public SimpleViewPager(Context context, AttributeSet attrs) {  
    10.         super(context, attrs);  
    11.     }  
    12.   
    13.     /** 
    14.      * android4.1+设置PageTransformer会使ViewPager的子页里面的触摸事件异常 
    15.      * (当前看到的子页并非在最上面,所以触摸事件被隐藏在其上面的View给消费了) 
    16.      * 所以结合setPageTransformer(),在onPageScrolled()里“手动”调用切换页面的动画 
    17.      * 
    18.      * @param position 
    19.      * @param offset 
    20.      * @param offsetPixels 
    21.      */  
    22.     @Override  
    23.     protected void onPageScrolled(int position, float offset, int offsetPixels) {  
    24.         super.onPageScrolled(position, offset, offsetPixels);  
    25.         // 下面的源码来自super.onPageScrolled()  
    26.         int scrollX;  
    27.         int childCount;  
    28.         int i;  
    29.         if (this.mPageTransformer != null) {  
    30.             scrollX = this.getScrollX();  
    31.             childCount = this.getChildCount();  
    32.   
    33.             for (i = 0; i < childCount; ++i) {  
    34.                 View var15 = this.getChildAt(i);  
    35.                 ViewPager.LayoutParams var16 = (ViewPager.LayoutParams) var15.getLayoutParams();  
    36.                 if (!var16.isDecor) {  
    37.                     float var17 = (float) (var15.getLeft() - scrollX) / (floatthis.getClientWidth();  
    38.                     this.mPageTransformer.transformPage(var15, var17);  
    39.                 }  
    40.             }  
    41.         }  
    42.     }  
    43.   
    44.     private int getClientWidth() {  
    45.         return this.getMeasuredWidth() - this.getPaddingLeft() - this.getPaddingRight();  
    46.     }  
    47.   
    48.     /** 
    49.      * 覆盖该方法,不设置PageTransformer,以成员变量的形式保存PageTransformer 
    50.      * 
    51.      * @param reverseDrawingOrder 
    52.      * @param transformer 
    53.      */  
    54.     @Override  
    55.     public void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) {  
    56.         super.setPageTransformer(reverseDrawingOrder, null);  
    57.         mPageTransformer = transformer;  
    58.     }  
    59.   

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


    然而,到这一步,并还没有完全搞定,你会发现滑动事件冲突了,点击事件也是有bug,特别是fragment里面有listview或者scrooview的,要把viewpaer的滑动事件处理交给下一层,代码如下:

    @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {

            try {
                return super.onInterceptTouchEvent(ev);
            } catch (Exception e) {
                // e.printStackTrace();
            }
            return false;
        }

        @Override
        public boolean onTouchEvent(MotionEvent arg0) {
            try {
                return super.onTouchEvent(arg0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }

        @Override
        protected boolean canScroll(View view, boolean arg1, int arg2, int arg3, int arg4) {
            if (view instanceof ViewPager) {
                return false;
            }
            return super.canScroll(view, arg1, arg2, arg3, arg4);
        }


    至此,问题就完美解决啦!



    展开全文
  • 5.0的系统会出现以下问题,4.4的系统则没问题 我使用了如下代码实现了ViewPager的动画切换效果 viewPager.setPageTransformer(true, new DepthPageTransformer()); 使用FragmentStatePagerAdapter将fragment作为...
  • 通过ViewPager.setPageTransformer()方法可以设置切换动画,但是如果ViewPager的子页中要处理触摸事件,如浏览图片时对图片放大缩小,ViewPager切换子页后,不能处理触摸事件,似乎子页里面的变的不可点击。...

    通过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

    展开全文
  • Viewpager的PageTransformer 不执行问题

    千次阅读 2016-04-11 16:42:48
    使用Viewpager来实现的,因为通过实现PageTransformer 接口,比较容易实现左右滑动的动画效果。由于项目里使用的android-support-v4.jar版本太老了 ,只有377kb,肯定小于android-support-v4 version13.0.0,此jar包...

    因为项目需求,要实现滑动大图且带影院效果,效果如下图所示:
    这里写图片描述
    使用Viewpager来实现的,因为通过实现PageTransformer 接口,比较容易实现左右滑动的动画效果。由于项目里使用的android-support-v4.jar版本太老了 ,只有377kb,肯定小于android-support-v4 version13.0.0,此jar包有个bug,就是初次显示viewpager时,动画效果没有执行(默认只有滑动时动画才会执行到),这样就导致两张图片连在一起,没有突出中间一张的效果了,如下图:
    这里写图片描述
    问题的解决方法本来很简单,就是用个高版本的jar包(support-v4-18.0.0及以上都可以)替换老的jar包就行了。
    这里写图片描述
    但是项目里一旦替换了jar,就会报65536那个错误,就是方法数太多了,没办法,只能投机取巧,在使用现有的老jar包基础上去改掉这个bug,最终的解决办法是,加载完数据后,手动调用一遍以下代码:
    if (mAdapter.getCount() > 1)
    {
    mTransformer.transformPage(mViewPager.getChildAt(1), 1);
    }
    当然当只有一条数据时,也就不存在这个bug了。
    mTransformer的实现如下:

    public class ScalePagerTransformer implements ViewPager.PageTransformer
    {
    
        public static final float MAX_SCALE = 1.0f;
    
        public static final float MIN_SCALE = 0.75f;
    
        public static final float MIN_ALPHA = 0.3f;
    
        @Override
        public void transformPage(View page, float position)
        {
            if (position < -1)
            {
                position = -1;
            }
            else if (position > 1)
            {
                position = 1;
            }
    
            float tempScale = position < 0 ? 1 + position : 1 - position;
    
            float slope = (MAX_SCALE - MIN_SCALE) / 1;
            // 一个公式
            float scaleValue = MIN_SCALE + tempScale * slope;
            page.setScaleX(scaleValue);
            page.setScaleY(scaleValue);
            if (position > -1 && position < 1)
            {
                // 加渐变透明效果,中间的view完全不透明
                page.setAlpha((1 - MIN_ALPHA) * tempScale + MIN_ALPHA);
            }
            else
            {
                page.setAlpha(MIN_ALPHA);
            }
    
            if (Build.VERSION.SDK_INT < 19 && page.getParent() != null)
            {
                page.getParent().requestLayout();
            }
        }
    }
    
    展开全文
  • viewPager.setPageTransformer(boolean, PageTransformer)方法设置PageTransformer时第一个参数给的false,应该设置true才对。 这是因为ViewPager默认下一个页面是绘制在上一个页面的上面,DepthPageTransformer对下...

    实际情况是你在调用 viewPager.setPageTransformer(boolean, PageTransformer)方法设置PageTransformer时第一个参数给的false,应该设置true才对。

    这是因为ViewPager默认下一个页面是绘制在上一个页面的上面,DepthPageTransformer对下一个页面的处理是只设为全透明,但还是位于屏幕中央。这样一来下一个页面虽然看不见,但实际上是存在于上一个页面的上面的,理所当然就会拦截事件。

    而第一个参数的意思就是是否要反转一下让下一个页面在上一个页面底下,因此在使用DepthPageTransformer的时候一定要设置为true。

    转载于:https://juejin.im/post/5cb41f7b5188251add7f1213

    展开全文
  • 项目中需要实现的效果如下图。 一般看到这种效果,条件反射我们会选择ViewPager+fragment方案,至于左右滑动效果,刚可以通过设置mViewPager.setPageTransformer(false,new ScaleTransformer())来实现。...
  • android viewpager 轮播图点击事件失效

    千次阅读 2016-12-05 17:19:07
    需要添加ontouch监听才可以,但是子控件添加ontouch事件返回false的话,只会响应down事件,所以要在viewpager添加ontouch事件,并且判断移动距离,避免拖动viewpager失效 OnTouchListener mOnTouchListener=new ...
  • 之前项目开发的时候要实现一种画廊效果,分别利用Gallery或ViewPager实现了该效果:
  • 本文解决ViewPager在实现gallery时,PageTransformer特效需要滑动一下才能生效的问题。 ViewPager版本:androidx-1.0.0。 复现问题前先复习下ViewPager实现gallery的方法: ViewPager可以实现gallery效果,核心...
  • Google在Android 3.0SDK中推出的ViewPager控件很大程度上满足了开发者开发页面左右移动切换的功能,使用非常方便,参见:http://jameszhao84.iteye.com/blog/1344584。但是使用中发现,在删除或者修改数据的时候,...
  • 一个Android ViewPager轮播图片Demo,支持自定义切换动画,兼容低版本。
  • Android3.0以上,ViewPager增加了切换动画,官方api说明有给出两个例子: ... DepthPageTransformer 以及 ZoomOutPageTransformer 我在使用时,发现如下问题:在我的代码中,viewPage
  • 前序故事:今天做一个viewpager碰见删除一个item不好使的问题,总是删除不掉,给我搞了半天没有搞定!当时我就纳闷了啊~这不该啊~虽然我技术很菜,但是不能连一个viewpager的基本用法都搞不懂吧~ ...
  • 1. 首先看一下最终的效果图2. 需求拆解第一眼看见上面的效果,是不是有些朋友觉得这个效果很酷,有的高手会觉得这个效果很简单。笔者昨天刚拿到需求的时候,最开始也是觉得这个很简单,可是越分析越发现好像实现出来...
  • 转载地址:https://github.com/youth5201314/banner 参考视频:... Android图片轮播控件 新框架发布,欢迎大家Star ...XFrame - Android快速开发框架 ...现在的绝大数app都有banner界面,实现循环播
  • 本文我们将讲解一个简单,强大的广告活动弹窗控件。不少App在打开的时候需要弹出一个广告活动弹窗,点击广告活动弹窗中的图片就会跳转到一个H5页面,加载显示具体的活动内容等,为了方便大家的操作,我将其做成了一...
  • 从PagerAdapter的notifyDataSetChanged方法源码入手解决ViewPager和PagerAdapter中调用notifyDataSetChanged失效的解决办法。 周末了,总结一下最近在项目中通过`ViewPager`和`PhotoView`做一个照片查看器的效果,...
  • 用法概述: 1、换页监听与换页方法 2、懒加载及预加载定制 3、设置间距与添加转场动画 4、轮播、禁止滑动与指示器的配合 这篇和下一篇都是偏向技巧的东西,对于前端开发者来讲,开发的应用是直接面对用户的,用户...
  • 1.在此我们引用 支持无限滑动的3D视觉的画廊效果、 平面普通广告栏轮播 这个例子中有可以运行的效果,大家可以下载下来先看一下,在我开始使用的时候,发现,想要调整 page item中的间距,比较困难,并没有暴露方法...
  • 现在的绝大数app都有banner界面,实现循环播放多个广告图片和手动滑动循环等功能。因为ViewPager并不支持循环翻页, 所以要实现循环还得需要自己去动手,我就把项目中的控件剔了出来,希望大家觉得有用。...
1 2 3
收藏数 42
精华内容 16
关键字:

pagetransformer 失效