利用ViewPager实现画廊Gallery效果

    • 1 需求确认
    • 2利用viewpager实现画廊效果
      • viewpager的继承关系
      • 使用ViewGroup的setClipChildrenboolean clipChildren方法
      • 使用viewpager的setPageTransformer方法实现vp页面切换效果
    • 3实战代码
      • 首先是父级布局
      • viewpager需要显示的内容
      • 实现画廊效果

1、 需求确认

最近做的一个小学的定制项目,谈需求的时候客户提到一个界面的效果。

客户:这个界面我们需要显示一张XX图片,但是它可以左右滑,为了知道它可以滑,需要在两边露一点比较小的图出来。

UI : 设计的原型图:

这是客户提出的需求,我们作为程序员需要转换为自己的理解:

这个界面我们需要使用列表进行展示,RecycleView或者Viewpager
关键是,左右需要露一点出来,如果用RecycleView的话需要让item占满全屏,左右露一点不太好实现,如果不让item占满全屏,就会出现滑动到两个item中间的情况。
所以应该是使用Viewpager,但是Viewpager怎么露出两侧的图呢?(我在网上游弋的时候,发现这种效果的名字叫做画廊,android有个控件Gallery就是用来实现这个效果的,但是现在不建议使用了,好贴切、好立体的名字。/(ㄒoㄒ)/~~原谅自己的无知,瞬间阿Q精神上身—-又找到一个可以装B的点了,O(∩_∩)O哈哈哈~)
so,我就稍稍必应了一下(本来想说百度了一下的,但是渣渣的百度搜索,我还是喜欢用必应,尤其是必应的bg图。O(∩_∩)O哈哈哈~),用viewpager是可以做到的,只是需要利用它的两个属性。

2、利用viewpager实现画廊效果

1 、viewpager的继承关系

2 、使用ViewGroup的setClipChildren(boolean clipChildren)方法

当然也可以在XML文件里面设置,属性为clipChildren

在代码中使用,就是setClipChildren()

这个方法或者属性的作用就是viewgroup的子view是否在它应有的边界内绘制。默认为true,在其边界内绘制。

so,我们就解决了核心的一点,怎么在两边露出图片的问题。接下来就是让切换的效果好看一点,切换的时候,把两边的图片变小一点,把中间的图片变大一点。

3 、使用viewpager的setPageTransformer(…)方法实现vp页面切换效果

这个方法的作用是,设置一个ViewPager.PageTransformer,每当更改滚动位置时,将为每个附加的页面调用它。意思就是VP切换界面的时候会调用这个ViewPager.PageTransformer以实现页面切换的动画效果。

其实许多ViewPager切换效果都是通过创建一个类实现ViewPager.PageTransformer然后重写transformPage方法来实现各种切换效果,放大缩小、旋转、倒影等等

3、实战代码

1 、首先是父级布局

代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/class_honor" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" android:gravity="center" tools:context="com.cnbs.eleclasscard.activity.growing.ClassHonorFragment">

    <ImageView  android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="-30dp" android:layout_marginBottom="50dp" android:src="@mipmap/bg_growing_class_honor" />

    <android.support.v4.view.ViewPager  android:id="@+id/class_honor_vp" android:layout_width="800dp" android:layout_height="600dp" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:layout_marginBottom="90dp" android:clipChildren="false"/>


</RelativeLayout>

特别说明:这个应用是在学校特定的设备上开发的,所以我根本没有考虑适配其他的设备O(∩_∩)O~

2 、viewpager需要显示的内容

就一张图片,所以在孩子fragment的布局文件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="20dp" tools:context="com.cnbs.eleclasscard.activity.growing.ClassHonorItemFragment">

  <ImageView  android:id="@+id/class_honor_img" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@mipmap/img_loading43"/>

</FrameLayout>

3 、实现画廊效果

1. viewpager和其父级布局都需要禁止让子view在其限制内绘制

private void initView() {
        classHonorVp.setClipChildren(false); //VP的内容可以不在限制内绘制
        classHonor.setClipChildren(false);  //VP可以不在限制内绘制
        adapter = new ClassHonorPageAdapter(getChildFragmentManager(), mContext, data); 
        classHonorVp.setAdapter(adapter);
        //实现画廊效果
        classHonorVp.setPageTransformer(true, new ZoomOutPageTransformer());   //实现需要的页面转换效果
        classHonorVp.setOffscreenPageLimit(2); //缓存页面数
        classHonorVp.setPageMargin(100); //每页的间隔
        //触摸事件反馈给viewpager
        classHonor.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return classHonorVp.dispatchTouchEvent(event);
            }
        });
    }

2. 创建一个类实现ViewPager.PageTransformer,实现页面转换效果

 //实现当前页面放大效果
    class ZoomOutPageTransformer implements ViewPager.PageTransformer {
        private static final float MAX_SCALE = 1.0f;
        private static final float MIN_SCALE = 0.7f;

        @Override
        public void transformPage(View view, float position) {
            if (position < -1) {
                view.setScaleX(MIN_SCALE);
                view.setScaleY(MIN_SCALE);
            } else if (position <= 1) {
                float scaleFactor = MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE - MIN_SCALE);
                view.setScaleX(scaleFactor);
                if (position > 0) {
                    view.setTranslationX(-scaleFactor * 2);
                } else if (position < 0) {
                    view.setTranslationX(scaleFactor * 2);
                }
                view.setScaleY(scaleFactor);
            } else {
                view.setScaleX(MIN_SCALE);
                view.setScaleY(MIN_SCALE);
            }

        }
    }

3. 补充一个,让左右都有图

 adapter.refresh(list);
 classHonorVp.setCurrentItem(1);

如果没有这个需求就不用,另外有时显示的效果没有处理,我们可以这样写:

classHonorVp.setCurrentItem(1);
classHonorVp.setCurrentItem(0);

你可能感兴趣的:(viewpager,画廊效果)