根据图片高度动态改变ViewPager高度方法的两种方式对比: PageTransformer& OnPageChangeListener

前言:师兄让我先试手一下完成蘑菇街index页面,在做到实现“根据图片高度动态改变ViewPager高度”时,我遇到了选择viewpager api的问题,然后自己试着对此进行了一点总结。

首先我根据师兄的提示使用了PageTransformer这个接口,但是发现用它写出来的效果会有一些细微的bug,其本身对用户体验的影响很小,但我想试试用另外一个接口OnPageChangeListener然后最终实现了相同的效果。

这里先对比一下两个接口内的方法

PageTransformer

  public void transformPage(View view, float position)

它只有这一个方法,如下:

这个方法的参数有两个viewposition,这个方法中的view指的是viewpager的直接操作的view,而position指的是相对于当前页面的位置:

position

position取值范围(-∞,+∞)当前值大于0且正在增大,说明这个page正在向右滑,若大于0切正在减小说明正在向左滑,小于0的情况同理。
PageTransformer这个借口是viewpager的内部类,实现这个借口的方法后,使用 :

mViewPager.setPageTransformer(true, new ZoomOutPageTransformer());

可以为每个item设置基于position变化的效果。

由于viewpager这个viewgroup的特殊性,它只会存当前页面加左右两个页面,共三个页面,所以当我们滑动页面时,如果在transformPage里log输出position,我们实际上能有同时收到3个item返回的position,不过因为他们位置的不同,position的变化范围不同,因此也较容易区分。

再观察transformPage这个方法,参数里只有view这个参数能获得当前item相对于adapter的位置,当我们要根据每个item的自身特性去做动画时,可以用ViewGroup中的getChildAt()方法来获得当前的View,用viewpager的方法getCurrentItem()来获得当前的item位于index的位置。

getCurrentItem()

这个方法的的返回值是当前的“趋势页面”,简言之就是你手指离开屏幕后viewpager停留的那个页面,此方法如下:

它返值回的是一个 int的值。

getChildAt(int a)

这个方法返回index里a位置的view,由于viewpager只缓存三个页面,所以单数一般不会大于2,若要取当前页面,则分情况:

a=0:getChildAt(0);

a>0: getChildAt(1);

OnPageChangeListener

此接口内有三个方法

1.public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

2.public void onPageSelected(int position);

3.public void onPageScrollStateChanged(int state);

其中第一个方法所提供的参数最为丰富

第一个参数,position,代表当前正在显示的第一个页面的索引,如果positionOffset不等于0,那么第position+1个页面将被显示。

第二个参数,positionOffset,代表position页面的偏移,取值范围是[0,1)。这是一个偏移百分比,类似于transformPage()中的position,但是有区别。

第三个参数,positionOffsetPixels,和第二个意义差不多,只不过单位是像素,偏移的像素值。

当我用log输出position 和getCurrentItem()的值时,发现如下:

上图是我在向右滑动ViewPager时log出的内容:可以发现一个规律:getCurrentItem()的返回值变为1时,position还是0。

上图是我在向左滑动ViewPager时log出的内容:position是0时,getCurrentItem()的返回值还是1,后变为0。

即,getCurrentItem()的返回值是当你手指离开屏幕时会做一判断,页面“即将“停留在第几页,则手指离开的一瞬间返回值为该页的索引。position则是当你向左滑动时,开始滑动的一瞬间就会将position置为(滑动前position)-1;向右滑动则会当页面完全填充viewpager时将position置为(滑动前position)+1

下面的代码是我实现能屈能伸ViewPager使用的OnPageChangeListener接口:

            ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    Log.e("---viewpager", "position:" + position + "--getCurrentItem:" + mViewPager.getCurrentItem());

                    if (mViewPager.getChildAt(1) != null) {
//                                                           ((RelativeLayout) mViewPager.getChildAt(1)).getChildAt(0).getHeight();
                        LinearLayout.LayoutParams ls = (LinearLayout.LayoutParams) mViewPager.getLayoutParams();
                        ls.height = (int) (heights[position] - (Math.abs(positionOffset) * (heights[position]
                                - heights[position + 1])));
                        mViewPager.setLayoutParams(ls);
                        float sc = positionOffset * ((float) heights[position + 1] / (float) heights[position] - 1) + 1;

                        if (position < mImageViews.size() - 1) {
                            if (heights[position] < heights[position + 1]) {
                                float scale = ((float) ls.height) / heights[position];
                                mImageViews.get(position).setScaleX(scale);
                                mImageViews.get(position).setScaleY(1);
                                scale = heights[position + 1] / (float) ls.height;
                                mImageViews.get(position + 1).setScaleX(1);
                                mImageViews.get(position + 1).setScaleY(scale);
//                                mImageViews.get(position + 1).getDrawable().setBounds(new Rect(0,top,ls.width,bottom));
                            } else {
                                float scale = ((float) ls.height) / heights[position + 1];
                                mImageViews.get(position + 1).setScaleX(scale);
                                mImageViews.get(position + 1).setScaleY(1);
                                scale = heights[position] / (float) ls.height;
                                mImageViews.get(position).setScaleX(1);
                                mImageViews.get(position).setScaleY(scale);

//                                mImageViews.get(position).getDrawable().setBounds(new Rect(0,top,ls.width,bottom));
                            }
                        }
//
                    }
                }

                @Override
                public void onPageSelected(int position) {

                }

                @Override
                public void onPageScrollStateChanged(int state) {

                }
            };

总结:根据上面的分析,我们应该可以得出胡结论:当我们需求的viewpager的变化与当面page的属性无关(即无论当前是第几个页面我们总是做相同的变换)时用PageTransformer较方便;当viewpager的变化与当前page有关时用
OnPageChangeListener较方便;

你可能感兴趣的:(android,UI)