pagetransformer 放大_pagetransformer - CSDN
精华内容
参与话题
  • 网上也有很多关于无限循环的实现方案,但是基本上都效果不是很好,没有根本上利用和掌握ViewPager和Adapter...我这里给大家讲解下最新的无限循环的实现方案以及下图这种缩放和透明度渐变的动画PageTransformer的方案。

    网上也有很多关于无限循环的实现方案,但是基本上都效果不是很好,没有根本上利用和掌握ViewPager和Adapter的展现原理,也基本没有复用View。

    我这里给大家讲解下最新的无限循环的实现方案以及下图这种缩放和透明度渐变的动画PageTransformer的方案。



    1、首先说无限循环,这个就要从PagerAdapter的下手。

     @Override
        public int getCount() {
            return mData.size() * 100;
        }
    里面有个getCount方法,这里默认设置个集合的大小,但是我们需要无限循环,所以这里我们可以设置足够大,但是一定要用集合的大小进行倍数相乘,方便后面的处理。

    还有个关键位置:

    int select = position < mData.size() ? position : (position % mData.size());
    这里要判断处理下,如果position大于集合的大小的话,我们这个position要处理下,就是除以集合的大小取余即可。
    
    
    2、接下来给大家一个详细的PagerAdapter的配置:
    package com.tandong.viewpagerdemo;
    
    import android.content.Context;
    import android.support.v4.view.PagerAdapter;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.tandong.viewpagerdemo.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class CardPagerAdapter extends PagerAdapter {
    
        private List<FrameLayout> mViews;
        private List<String> mData;
        private Context context;
    
        public CardPagerAdapter(Context context, List<String> list) {
            this.context = context;
            mViews = new ArrayList<FrameLayout>();
            this.mData = list;
            for (int i = 0; i < list.size(); i++) {
                mViews.add(null);
            }
        }
    
        @Override
        public int getCount() {
            return mData.size() * 100;
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = LayoutInflater.from(container.getContext())
                    .inflate(R.layout.item_card, container, false);
            container.addView(view);
            FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.ll_container);
            ImageView iv_img = (ImageView) view.findViewById(R.id.iv_img);
            TextView tv_select = (TextView) view.findViewById(R.id.tv_select);
            int select = position < mData.size() ? position : (position % mData.size());
            Log.i("info", "位置:" + select + "  " + position + "  " + (position / mData.size()) + "  " + (position % mData.size()));
            tv_select.setText("" + select);
            mViews.set(select, frameLayout);
            return view;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
            int select = position < mData.size() ? position : (position % mData.size());
            mViews.set(select, null);
        }
    
    }
    3、接下来说渐变的PageTransformer:
    package com.tandong.viewpagerdemo;
    
    import android.support.v4.view.ViewPager;
    import android.util.Log;
    import android.view.View;
    
    public class TransFormer implements ViewPager.PageTransformer {
        public static float MIN_ALPHA = 0.5f;
        public static float MIN_SCALE = 0.8f;
    
        @Override
        public void transformPage(View page, float position) {
            if (position < -1 || position > 1) {
                page.setAlpha(MIN_ALPHA);
                page.setScaleX(MIN_SCALE);
                page.setScaleY(MIN_SCALE);
                Log.i("info", "缩放:position < -1 || position > 1");
            } else if (position <= 1) { // [-1,1]
                float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
                if (position < 0) {
                    float scaleX = 1 + 0.2f * position;
                    Log.i("info", "缩放:position < 0");
                    page.setScaleX(scaleX);
                    page.setScaleY(scaleX);
                } else {
                    float scaleX = 1 - 0.2f * position;
                    page.setScaleX(scaleX);
                    page.setScaleY(scaleX);
                    Log.i("info", "缩放:position <= 1 >=0");
                }
                page.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
            }
        }
    }

    4、最后给一个完整的调用:
    package com.tandong.viewpagerdemo;
    
    import android.os.Bundle;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    import com.tandong.viewpagerdemo.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
        private ViewPager vp;
        private CardPagerAdapter cardPagerAdapter;
        private List<String> lists;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            vp = (ViewPager) this.findViewById(R.id.vp);
            lists = new ArrayList<String>();
            for (int i = 0; i < 5; i++) {
                lists.add("");
            }
            cardPagerAdapter = new CardPagerAdapter(this, lists);
    //        vp.setPageMargin(10);
            vp.setOffscreenPageLimit(3);
            vp.setPageTransformer(false, new TransFormer());
            vp.setAdapter(cardPagerAdapter);
            vp.setCurrentItem(cardPagerAdapter.getCount() / 2);
        }
    }

    这里要实现这个一个界面有3个View的ViewPager效果,需要注意在ViewPager所在的布局里设置:
    android:clipChildren="false"
    把ViewPager和父布局分别设置这个属性,然后把ViewPager分别设置:
    android:layout_marginLeft="80dp"
    android:layout_marginRight="80dp"
    这样才可以实现一个界面3个View的ViewPager效果。
    
    
    
    
    


    展开全文
  • 自定义PageTransformer实现类似Gallery效果

    废话不多说了,先看看效果
    demo效果图
    接下来,我们分析一下实现过程。
    首先,使用ViewPager实现类似Gallery效果只需要在布局文件上加上android:clipToPadding=”true”就行。clipToPadding这个属 性指的是是否允许子组件布局到父组件的padding区域,默认是true,即不允许。将这个属性设置为false之后,就能实在在同一个屏幕显示多个PageView的效果。

           <android.support.v4.view.ViewPager
                android:id="@+id/view_pager"
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:overScrollMode="never"
                android:layout_centerInParent="true"
                android:clipToPadding="false"
                android:paddingLeft="70dp"
                android:paddingRight="70dp">
    
            </android.support.v4.view.ViewPager>

    其次是要实现page页的切换效果。要实现切换效果就要使用ViewPager的PageTransformer类。如果我们的page是横向满屏的话,直接继承该类就行。例如实现切换时的缩放效果,代码可以简单的这么写:

    public class ScalePageTransformer implements ViewPager.PageTransformer {
    
        public static final float MIN_SCALE = 0.75f;
    
        @Override
        public void transformPage(View page, float position) {
    
            if (position < -1) { // [-Infinity,-1)
                page.setScaleX(MIN_SCALE);
                page.setScaleY(MIN_SCALE);
    
            } else if (position <= 1) { // [-1,1]
                float scaleFactor = MIN_SCALE
                        + (1 - MIN_SCALE) * (1 - Math.abs(position));
                page.setScaleX(scaleFactor);
                page.setScaleY(scaleFactor);
    
            } else { // (1,+Infinity]
                page.setScaleX(MIN_SCALE);
                page.setScaleY(MIN_SCALE);
    
            }
    
        }
    
    }

    但是如果我们的想要在同一个屏幕显示多个page,那么,我们就会发现,同样使用上面的代码,当page放大到最大的时候,page的位置并不在屏幕的正中间,而是在屏幕的最左侧。
    通过ViewPager的源代码,我们发现,问题就出在transformPage的pisition参数上,ViewPager相关源码如下:

    if (mPageTransformer != null) {
                final int scrollX = getScrollX();
                final int childCount = getChildCount();
                for (int i = 0; i < childCount; i++) {
                    final View child = getChildAt(i);
                    final LayoutParams lp = (LayoutParams) child.getLayoutParams();
    
                    if (lp.isDecor) continue;
                    final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();
                    mPageTransformer.transformPage(child, transformPos);
                }
    }
    
    private int getClientWidth() {
            return getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    }
    

    我们发现position表示的是page页左侧到屏幕左侧的距离与ViewPager内容区域(除去padding区域)的比值。因此当position的值为0的时候,page页左侧正好与屏幕左侧重合,这显然不是我们想要的。那么我们就可以参考ViewPager的源码,改进position的计算方式,达到我们需要的效果。参考代码如下:

    package demo.xuqingqi.cardviewpager;
    
    import android.support.v4.view.ViewPager;
    import android.view.View;
    
    /**
     * Created on 2016/8/29.
     */
    public class ScalePageTransformer implements ViewPager.PageTransformer {
    
        public static final float MIN_SCALE = 0.75f;
    
        /**
         * 重新计算 page 的位置transformPos,使得
         * 当page居中时 transformPos为0
         * 当page向左偏移时 transformPos为[-Infinity, 0)
         * 当page向右偏移时 transformPos为(0, +Infinity]
         */
        @Override
        public void transformPage(View page, float position) {
    
            ViewPager viewPager = (ViewPager) page.getParent();
            int scrollX = viewPager.getScrollX();
            int clientWidth = viewPager.getMeasuredWidth() -
                    viewPager.getPaddingLeft() - viewPager.getPaddingRight();
            int offsetX = page.getLeft() - scrollX;
            int parentWidth = viewPager.getMeasuredWidth();
            int childWidth = page.getWidth();
            float deltaX = (float) (parentWidth - childWidth) / 2;
            float transformPos = (offsetX - deltaX) / clientWidth;
    
            if (transformPos < -1) { // [-Infinity,-1)
                page.setScaleX(MIN_SCALE);
                page.setScaleY(MIN_SCALE);
    
            } else if (transformPos <= 1) { // [-1,1]
                float scaleFactor = MIN_SCALE
                        + (1 - MIN_SCALE) * (1 - Math.abs(transformPos));
                page.setScaleX(scaleFactor);
                page.setScaleY(scaleFactor);
    
            } else { // (1,+Infinity]
                page.setScaleX(MIN_SCALE);
                page.setScaleY(MIN_SCALE);
    
            }
    
        }
    
    }

    另附demo:github地址

    展开全文
  • viewPager.PageTransformer 页面滑动时候处理图片缩放效果
    class ScalePagerTransformer implements ViewPager.PageTransformer {
            //最小缩放率
            private static final float MIN_SCALE = 0.85f;
            //最小的透明度
            private static final float MIN_ALPHA = 0.5f;
            //这个就是在viewpager 页面滑动的时候会回调这个方法
            @Override
            public void transformPage(View view, float position) {
                //当前的图片位置 ,viewpager设置显示3个图片,最左边的为-1 中间为0  右边位置为1
                if (position >= -1 || position <= 1) {
                    //图片高
                    final float height = view.getHeight();
                    //图片宽
                    final float width = view.getWidth();
                    //缩放因子,    如果是中间位置0,得到因子为1,不缩放,如果为-1或者1得到缩放因子为0.85,就进行缩放
                    //                                    0.85        如果为中间位置,这就是0 ,Math.abs = 0
                    final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
                    //            求出来图片要进行缩放后的高度,如果为中间位置,scaleFactor =1 ,那么这个vertMargin = 0
                    //          如果是两边位置scaleFactor = 0.85  得到vertMargin = height*0.15/2
                    final float vertMargin = height * (1 - scaleFactor) / 2;
                    final float horzMargin = width * (1 - scaleFactor) / 2;
                    // 这个方法就是进行缩放所指定的中心点的位置,就是图片的中心点
                    view.setPivotX(0.5f * height);
                    view.setPivotY(0.5f * width);
                    //这个是进行位移,应该是处理两个图片之间的间距
                    if (position < 0) {
                        view.setTranslationX(horzMargin - vertMargin / 2);
                    } else {
                        view.setTranslationX(-horzMargin + vertMargin / 2);
                    }
                    //进行缩放
                    view.setScaleX(scaleFactor);
                    view.setScaleY(scaleFactor);
                    //进行透明度处理 ,比如如果是在中间位置  0.5 + (1 - 0.85)/(1-0.85)*(1-0.5)= 0.5+0.15/0.15 * 0.5 = 0.5+0.5 = 1
                                // 如果是两边位置 0.5 + (0.85 - 0.85)/(1-0.85)*(1-0.5) = 0.5,进行半透明处理
                    view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
                }
            }
        }
    展开全文
  • Android的ViewPager类已经变成一个...标准的ViewPager实现工作得非常出色,但是在Google工作的牛人创建了名为PageTransformer的类。PageTransformer是一个接口,它允许你修改默认的页幻灯片动画。这样做你可以创建...

    Android的ViewPager类已经变成一个相当流行的Android应用组件了。它简单直观,并且提供了极好的功能。你可以经常在设置向导,图片画廊种看到它,它还是分开应用内容的良好方式。

    标准的ViewPager实现工作得非常出色,但是在Google工作的牛人创建了名为PageTransformer的类。PageTransformer是一个接口,它允许你修改默认的页幻灯片动画。这样做你可以创建各种各样出色的幻灯片效果和动画。

    那么它是如何工作的呢?根据这个开发者教程,你开始实现ViewPager.PageTransformer接口并注册到view pager实例中。该接口暴露单一的方法,transformPage(),该方法在可视页面和相邻的下一个要显示的页面做屏幕切换时被调用。

    我们现在可以开始基于页面位置绘制动画了,页面位置可以从transformPage()方法的position参数获得。

    “position参数指明了给定页面相对于屏幕中心的位置。它是一个动态的属性,会根据用户滑动页面时变化。当一个页面充满屏幕时,它的position值为0。当一个页面被绘制在屏幕的右侧,它的position值为1。如果用户滑到一半,在页面1和页面2之间是,页面1的position值为-0.5,页面2的position值为0.5”。

    现在我们了解了转换器是如何工作的,我们就可以开始相对页面的位置动画它们的属性了。它们可以是任何属性,比如透明度、X轴/Y轴(甚至是Android L+中的Z轴)变换、缩放、旋转等。

    Android开发者中心提供了一堆出色的切换。

    这甚至有一个定制的内置切换库!

    别急,还有更多

    真正的乐趣开始于你启动页面内元素的动画!

    transformPage()方法提供了position值和页面的视图。通常,我们对视图进行动画。但我们并不局限于视图!我们还可以对视图内的子视图进行变换!(太多的“视图”…下面是一个)

    来看看这个!

    这是我的应用Tholotis,它有一个2页的ViewPager。开始滚动时,你可能会注意到视图的X轴值根据不同的速度进行水平移动

    我究竟是怎么做得到的呢?!很容易…

    一个优秀的例子是Yahoo的天气应用,它因这个特性变得流行。看看下面的gif。ViewPager的页面滑动的很正常,因为它的图片移动速度是正常速度的一半。

    他们究竟是怎么做得到的呢?!很容易…

    Yahoo一直在使用其他应用(如News Digest和Flickr)所使用的同样技术。Flickr的动画有一些复杂,因为它们使用了帧动画(gif)和位置值来创建3D效果/错觉。

    总结

    PageTransformer接口一个是强有力的工具。用上你的出色开发者技能以及一些创造力,你就可以创造出令人惊叹的动画,让用户喜爱你的应用。

    前进吧,少年。

    还不快去试一试…

    转载于:https://www.cnblogs.com/duadu/p/6167284.html

    展开全文
  • /**稀土掘金,时光不老**/ 大家好,很早就想写博客了,一是工作忙,二是缺乏原创性,三当然是自己的能力不够啦,写这篇博客是很惶恐。。。。请多多包涵 /**************************** -------- --------- ...
  • 看到有同事在用土巴兔这个app,看了里面的一些效果非常的不错,就试着模仿了一下,这里通过ViewPager来实现的
  • 画廊式中间放大效果
  • 技术这东西就是需要日积月累的,每天学习一...今天复习一个小知识点,就是用ViewPager+Fragment+PageTransformer实现滑动动画,很简单,最后我会将源码demo下载地址附上,高手略过啊。 首先我们来看一下第一个效果:
  • Android ViewPager切换动画PageTransformer

    千次阅读 2017-06-17 21:51:33
    PageTransformerViewPager的默认切换视图的动画是平移方式,如果希望能改变默认的动画效果,增加淡入淡出,缩小放大等效果时,可以实现ViewPager.PageTransformer接口,并将它设置给ViewPager。 public interface ...
  • 今天在使用PageTransformer做滑动缩放效果时发现缩放的位置有偏差,正常来说应该在最正中间放大至最大,但我在滑动时发现在偏左的位置才达到最大化,停留在正中间时反而会缩小一些,确认PageTransformer内代码写得没...
  • 通过ViewPager.setPageTransformer()方法可以设置切换动画,但是如果ViewPager的子页中要处理触摸事件,如浏览图片时对图片放大缩小,ViewPager切换子页后,不能处理触摸事件,似乎子页里面的变的不可点击。...
  • 一直想写个自己用的APP,将日常关注网站展现在一个app,方便个人兴趣阅读学习,刚好大舅也有一个给学生推荐课程定向学习的需求,这里介绍一个市场常见的展示效果:ViewPage实现当前视图放大左右视图露边及点击事件...
  • 利用给自定义PageTransformer,给viewpager设置不同的切换特效,多种特效的欢迎页面
  • ViewPager设置切换动画PageTransformer

    千次阅读 2018-06-29 23:00:47
    这里记录下viewpager中的切换之间的渐变以及间距的动画 1、设置间距并展示多个页面边缘 主要是这个属性android:clipChildren=”false”表示的意思是: clipChild用来定义他的子控件是否要在他应有的边界内进行...
  • Android利用ViewPager实现滑动放大缩小

    千次阅读 2018-09-13 10:54:42
    效果图: 实现这个效果需要先处理布局文件 处理如下: ViewPager控件的父布局需要设置 android:clipChildren="false"...这个属性的解释是Defines whether a child is limited to draw inside of its ...
  • http://blog.csdn.net/lmj623565791/article/details/40411921http://blog.csdn.net/lmj623565791/article/details/38026503
  • 在之前的项目中,要做店员快速登录的一个界面,入下图所示:  上面这个需求,首先想到的就是viewpager来实现这个效果。 首先,就是让viewpa能显示多个图片,这个在网上搜一下,有很多的讲这个的,要让viewpager...
  • 首先放效果图,此次的需求是希望一共3张图片,中间突出显示,左右两侧随着滑动放大缩小,并且点击左右两侧可以切换图片.这样的效果其实是挺少见的,本人在网上找的大部分是用recyclerview实现的但是左右两侧都是被盖住的,...
  • Android动画初见

    2016-11-29 16:21:34
    概述: 动画可以为我们的App增加精细的视觉提示,并且能改进App界面的思维模型。当界面改变其状态时(例如加载内容或新操作可用时),动画特别有帮助。另外,动画也能让我们的App外观更加优雅,为用户提供一种更好...
  • 无限循环 在PagerAdapter.getCount();方法里返回Integer.MAX_VALUE。设置图片用ImageView.setBackgroundDrawable(pics[position % pics.length];来实现伪无限循环。 在第一页的前边和最后一页的后边添加两个缓冲页P...
1 2 3 4 5 ... 11
收藏数 208
精华内容 83
关键字:

pagetransformer 放大