使用ViewPager实现gallery

整理自http://blog.csdn.net/u012702547/article/details/52334161,记录一下对于PageTransform的理解。

原理分析

通过设置clipChildren或者clipToPadding属性,使得ViewPager可以实现单屏多页的效果。

ViewPager的特性就是每一页View的宽度是ViewPager宽度减去ViewPager的padding,所以要实现单屏多页的效果,有两种方法。

方法一是设置ViewPager的margin和clipChildren属性,clipChildren属性表示子控件是否可以绘制在本身边界之外,默认该属性为true,即不可绘制在本身边界外。通过在ViewPager及其父布局两个地方都声明clipChildren=”false”,就可以在ViewPager范围之外画出其他页的内容。这一方法的问题在于其他页的内容无法响应点击事件。

方法二是设置ViewPager的padding和clipToPadding属性,clipToPadding属性表示子控件是否可以绘制在父布局的padding之中,默认为true。只要在ViewPager处声明clipToPadding=”false”,ViewPager的page范围是不包含padding的,就可以显示出单屏多页,还可以响应点击事件。

示例代码

以下以clipToPadding的具体做法作为示例。

ViewPager的xml:

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:paddingLeft="130dp"
    android:paddingRight="130dp"
    android:clipToPadding="false"
    android:layout_height="200dp">

有几个点需要明确一下:

  1. ViewPager的setPageMargin()是用来指定每页间的间隔,而这个间隔对于每一页的宽度是没有影响的,即每一页的宽度总是等于ViewPager不包含padding在内的宽度。

  2. ViewPager的setOffscreenPageLimit()用来指定屏幕外额外加载的页数。

  3. ViewPager.PageTransform的回调方法transformPage(View page, float position)中page是某一个可见page,position是该page相对于ViewPager当前正中page的位置偏移比例,该比例以page宽度为准。所以在每一次ViewPager滑动位置改变的时候,对于每个可见page都会回调该方法。

  4. 如果需要进行PageTransform,如果是clipChildren方法,ViewPager的整体宽度与page宽度是一致的,ViewPager.PageTransformer回调的position也符合-1,0,1的规律。
    但是如果是clipToPadding方法,因为有padding的存在,ViewPager的整体宽度大于page的实际宽度,所以ViewPager.PageTransformer回调的position会跟随着padding的不同而不同,具体观察到的规律是以page实际宽度为基准,到ViewPager最左边的距离去计算position。回调得到的position就会比clipChildren方法中的大,具体数值是左padding除以page宽度,所以为了变换的准确,需要减去这个值。

  5. 如果要控制page的宽度,只能通过控制padding来实现。

ViewPager的具体设置:

private ArrayList<View> mViews;
private static final float MIN_ALPHA = .5f;
private static final float MIN_SCALE = .6f;
private static final float MAX_SCALE = 1f;

...

private void initPager() {
    final ViewPager pager = (ViewPager) findViewById(R.id.pager);
    pager.setPageMargin(80);
    pager.setOffscreenPageLimit(2);
    // 此处通过获取ViewPager两边的padding来计算每一页实际宽度
    final int paddingLeft = pager.getPaddingLeft();
    final int screenWidth = getResources().getDisplayMetrics().widthPixels;
    int pageWidth = screenWidth - 2 * paddingLeft;
    // 左边padding相对于page宽度的比例
    final float ratioOfPadding2PageWidth = paddingLeft * 1f / pageWidth;

    mTransformer = new ViewPager.PageTransformer() {
        @Override
        public void transformPage(View page, float position) {
            position -= ratioOfPadding2PageWidth;
            Log.e(TAG, "page = " + page.getTag() + ", position = " + position);
            if (position < -1 || position > 1) {
                page.setAlpha(MIN_ALPHA);
                page.setScaleX(MIN_SCALE);
                page.setScaleY(MIN_SCALE);
            } else {
                if (position < 0) {
                    page.setScaleX(MIN_SCALE + (MAX_SCALE - MIN_SCALE) * (1 + position));
                    page.setScaleY(MIN_SCALE + (MAX_SCALE - MIN_SCALE) * (1 + position));
                    page.setAlpha(MIN_ALPHA + (1 - MIN_ALPHA) * (1 + position));
                } else if (position >= 0) {
                    page.setScaleX(MIN_SCALE + (MAX_SCALE - MIN_SCALE) * (1 - position));
                    page.setScaleY(MIN_SCALE + (MAX_SCALE - MIN_SCALE) * (1 - position));
                    page.setAlpha(MIN_ALPHA + (1 - MIN_ALPHA) * (1 - position));
                }
            }
        }
    };
    pager.setPageTransformer(false, mTransformer);

    final View layout1 = getLayoutInflater().inflate(R.layout.layout1, null);
    final View layout2 = getLayoutInflater().inflate(R.layout.layout2, null);
    final View layout3 = getLayoutInflater().inflate(R.layout.layout3, null);
    final View layout11 = getLayoutInflater().inflate(R.layout.layout1, null);
    final View layout22 = getLayoutInflater().inflate(R.layout.layout2, null);
    final View layout33 = getLayoutInflater().inflate(R.layout.layout3, null);

    mViews = new ArrayList<>();
    mViews.add(layout1);
    mViews.add(layout2);
    mViews.add(layout3);
    mViews.add(layout11);
    mViews.add(layout22);
    mViews.add(layout33);

    pager.setAdapter(new PagerAdapter() {
        @Override
        public int getCount() {
            return mViews.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(mViews.get(position));
return mViews.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(mViews.get(position));
        }
    });
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值