ViewPager之onPageScrolled的动画

  其实这篇文章早就想写了,一直没空,马上就要出差了,于是想在出差前把这个赶紧写出来,要不真是到猴年马月了。

   首先一张gif镇楼,无图无真相,只有图才能让你看到我今天要写的内容是什么,也不浪费各位大佬的时间。


这是我们的Ui 设计的一款 APP 引导图,其实刚定下这个需求的时候,我们的UI 已经自己把这个效果在ProtoPie 上 效果给做出来了。

当时还在忙其他的事情,第一眼看到他 给的这个效果,瞬间感觉懵逼了,看似简单,其中的左右两个色块是要跟着联动的,而且 除了左右的2个色块,其他的所有元素

都是要 渐变的。 而且不是单一的一个动画的渐变,是要根据Viewpager 的滑动 的量来 动态设置 透明度,可能我这个gif不太明显吧。

总的来说,对我这个菜鸟是一个挑战。因为那时候我 的实习期刚 结束,我自己的基础,还有这些组件的原理都不清楚。 觉得好有压力。但是后来,我看到我们的ios 小伙伴已经吧这个效果搞出来了,我特么瞬间就来脾气了,不服气,Android 怎么能输给 IOS,MMP。说干就干。 然后专心 一点一点的调试效果。出乎我自己的意料。一下午不到,这个效果就出来了。堪称我最 得以的一个模块了。


废话不多说,开始讲解,其实ViewPager 大家都 在熟悉不过了,基本用的都是监听这个onPageScrolled (int position,float positionOffset ,int positionOffsetPixels)

分别 position -->当前页面,即点击滑动的页面 ; positionOffset-->  当前页面偏移的百分比 ;   positionOffsetPixels --> 当前页面偏移的像素位置  

 然后主要我使用的是  前2个参数。来达到这个效果。

首先是布局XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/guidepage_black_bg">
    <!--橘色的色块图-->
    <ImageView
        android:id="@+id/iv_guidepage_left_colorlump"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/guidepage_left_animation_bg" />
    <!--白色的色块图-->
    <ImageView
        android:id="@+id/iv_guidepage_right_colorlump"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/guidepage_right_animation_bg" />

    <android.support.v4.view.ViewPager
        android:id="@+id/guidepage_viewpager_gdu_pro"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!--上方的文字 Text 1 -->
    <TextView
        android:id="@+id/tv_guidepage_content01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/pf_ui_size_74"
        android:gravity="center"
        android:text="@string/Label_guidepage_Page_Text_01"
        android:textColor="@color/pf_color_ffffff"
        android:textSize="@dimen/pf_text_size_50" />
    <!--上方的文字 Text 2 -->
    <TextView
        android:id="@+id/tv_guidepage_content02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/pf_ui_size_74"
        android:gravity="center"
        android:text="@string/Label_guidepage_Page_Text_02"
        android:textColor="@color/pf_color_ffffff"
        android:textSize="@dimen/pf_text_size_50" />
    <!--上方的文字 Text 3 -->
    <TextView
        android:id="@+id/tv_guidepage_content03"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/pf_ui_size_74"
        android:gravity="center"
        android:text="@string/Label_guidepage_Page_Text_03"
        android:textColor="@color/pf_color_ffffff"
        android:textSize="@dimen/pf_text_size_50" />
   <!--下方的指示器-->
    <LinearLayout
        android:id="@+id/ll_guidepage_dots_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="@dimen/pf_ui_size_76"
        android:orientation="horizontal">
        <!--point 1 -->
        <View
            android:id="@+id/guide_v_dot1"
            style="@style/splash_dot_style" />
        <!--point 2 -->
        <View
            android:id="@+id/guide_v_dot2"
            style="@style/splash_dot_style" />
        <!--point 3 -->
        <View
            android:id="@+id/guide_v_dot3"
            style="@style/splash_dot_style" />

    </LinearLayout>


</RelativeLayout>
主要的图片 贴下 







然后其他的看代码就都能看懂了。

问题就在于如果 很好的移动这些简单的布局 元素,然后 达到产品和UI 想要的效果。


重点来了, 先贴重点代码。

 mViewPage.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                setIndicatePoints(position);
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                setTextAnimation(position, positionOffset);// 文案

                setViewPagerPicAlpha(position,positionOffset);//Viewpager

                if (position == 2) mll_Points_layout.setAlpha(1 - positionOffset);// 指示器 layout

                // 背景(黄 白)色块
                mIv_left_pic.setTranslationX(-(EVERY_OFFSET_X_SUM * (positionOffset + position)));
                mIv_right_pic.setTranslationX(EVERY_OFFSET_X_SUM * (positionOffset + position));
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
 没错,就这么点,就是整个 gif 的效果 。

其实最早 就是这2句代码,后期经过 不断的测试和 测试,然后以此类推 其他的也就不难了

 // 背景(黄 白)色块
                mIv_left_pic.setTranslationX(-(EVERY_OFFSET_X_SUM * (positionOffset + position)));
                mIv_right_pic.setTranslationX(EVERY_OFFSET_X_SUM * (positionOffset + position));


,就这两句代码,因为不懂的计算。不懂原理,就是一点的的测试。


GuideActivity.java
/**
 * <p>GDU pro  guidepage 引导页</p>
 */
public class GuideActivity extends Activity {

    // pager 页数
    private final static int PAGE_COUNT = 4;
    // 指示灯 个数
    private final static int DOT_COUNT = 3;
    // 1208 x 720 的标准位移 量(UI 给)
    private float X_OFFSET = 124;
    // 因为是4个 pager 但是只位移了 3次,
    private float MOVE_PERCENT = 1.444f;
    // 每一个pager  位移X 的总量
    private float EVERY_OFFSET_X_SUM;

    // 基本元素
    private View[] mPoints = new View[DOT_COUNT];
    private PageView mPageViews[] = new PageView[PAGE_COUNT];
    // find view
    // 文案的个数
    private TextView content01, content02, content03;
    private MyPageAdapter myPagerAdapter;
    private LinearLayout mll_Points_layout;
    private ViewPager mViewPage;
    private ImageView mIv_left_pic;
    private ImageView mIv_right_pic;
    // 帮助类

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.guidepage_gdupro_layout);
        initView();
        initData();
        initViewPager();
        setIndicatePoints(0);// 设置第一个指示点
        setTextAnimation(0, 0);// 设置 text 文案
    }

    private void initView() {
        content01 = (TextView) findViewById(R.id.tv_guidepage_content01);
        content02 = (TextView) findViewById(R.id.tv_guidepage_content02);
        content03 = (TextView) findViewById(R.id.tv_guidepage_content03);
        content02.setAlpha(0);
        content03.setAlpha(0);
        mIv_left_pic = ((ImageView) findViewById(R.id.iv_guidepage_left_colorlump));
        mIv_right_pic = ((ImageView) findViewById(R.id.iv_guidepage_right_colorlump));
        mViewPage = (ViewPager) findViewById(R.id.guidepage_viewpager_gdu_pro);
        mll_Points_layout = ((LinearLayout) findViewById(R.id.ll_guidepage_dots_layout));
        mPoints[0] = findViewById(R.id.guide_v_dot1);
        mPoints[1] = findViewById(R.id.guide_v_dot2);
        mPoints[2] = findViewById(R.id.guide_v_dot3);
    }

    private void initData() {
        // 根据手机屏幕大小算出 图片块的偏移量
        X_OFFSET = (UavStaticVar.screenWidth /UavStaticVar.screenHeight) * X_OFFSET;
        // 计算一个 pager 页面需要偏移的总量
        EVERY_OFFSET_X_SUM = X_OFFSET * MOVE_PERCENT;
    }

    /**
     * <p> viewpager 事件</p>
     */
    private void initViewPager() {

        mPageViews[0] = new PageView(R.mipmap.guidepage_viewpage1_cn, R.mipmap.guidepage_viewpage1_en);
        mPageViews[1] = new PageView(R.mipmap.guidepage_viewpage2_cn, R.mipmap.guidepage_viewpage2_en);
        mPageViews[2] = new PageView(R.mipmap.guidepage_viewpage3, R.mipmap.guidepage_viewpage3);
        mPageViews[3] = new PageView(R.mipmap.guidepage_viewpage4, R.mipmap.guidepage_viewpage4);

        myPagerAdapter = new MyPageAdapter();
        mViewPage.setAdapter(myPagerAdapter);

        mViewPage.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                setIndicatePoints(position);
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                setTextAnimation(position, positionOffset);// 文案

                setViewPagerPicAlpha(position,positionOffset);//Viewpager

                if (position == 2) mll_Points_layout.setAlpha(1 - positionOffset);// 指示器 layout

                // 背景(黄 白)色块
                mIv_left_pic.setTranslationX(-(EVERY_OFFSET_X_SUM * (positionOffset + position)));
                mIv_right_pic.setTranslationX(EVERY_OFFSET_X_SUM * (positionOffset + position));
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }
    /**
     * <p>引导页 文字显示 的 渐变 出现和显示</p>
     *
     * @param currentPosition
     * @param positionOffset
     */
    public void setTextAnimation(int currentPosition, float positionOffset) {
        if (currentPosition == 0) {
            content01.setVisibility(View.VISIBLE);
            content01.setAlpha(1 - positionOffset);
            content02.setAlpha(positionOffset);
        } else if (currentPosition == 1) {
            content02.setVisibility(View.VISIBLE);
            content02.setAlpha(1 - positionOffset);
            content03.setAlpha(positionOffset);
        } else if (currentPosition == 2) {
            content03.setAlpha(1 - positionOffset);
            content03.setVisibility(View.VISIBLE);
        } else {
            content01.setVisibility(View.GONE);
            content02.setVisibility(View.GONE);
            content03.setVisibility(View.GONE);
        }
    }
    /**
     * <p>设置图片的Alpha</p>
     */
    public void setViewPagerPicAlpha(int currentPosition, float positionOffset) {
        if (currentPosition == 0) {
            mPageViews[0].getiPageView().setAlpha(1 - positionOffset);
            mPageViews[1].getiPageView().setAlpha(positionOffset);
        } else if (currentPosition == 1) {
            mPageViews[1].getiPageView().setAlpha(1 - positionOffset);
            mPageViews[2].getiPageView().setAlpha(positionOffset);
        } else if (currentPosition == 2) {
            mPageViews[2].getiPageView().setAlpha(1 - positionOffset);
            mPageViews[3].getiPageView().setAlpha(positionOffset);
        }
    }

    /**
     * <p>指示点 显示</p>
     *
     * @param currentPosition
     */
    public void setIndicatePoints(int currentPosition) {
        for (int i = 0; i < mPoints.length; i++) {
            if (currentPosition == i) {
                mPoints[i].setSelected(true);
            } else {
                mPoints[i].setSelected(false);
            }
        }
        if (currentPosition == 3) {
            mPoints[2].setSelected(true);
        }

    }

    /**
     * <p>Viewpager 适配器</p>
     */
    private class MyPageAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            if (null != mPageViews) {
                return mPageViews.length;
            }
            return 0;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(mPageViews[position].getiPageView());
            return mPageViews[position].getiPageView();
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(mPageViews[position].getiPageView());
        }

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

    private class PageView {
        private View iPageView;

        public PageView(int cn_resid, int en_resid) {
            iPageView = View.inflate(getBaseContext(), R.layout.guidepage_gdupro_viewpager_item, null);
            ImageView imageView = (ImageView) iPageView.findViewById(R.id.Iv_guidepage_item_pic);
            ImageView clickOpen = (ImageView) iPageView.findViewById(R.id.Tv_guidepage_in_app);

            if (UavStaticVar.LanguageType.equals("zh")) {
                imageView.setImageResource(cn_resid);
            } else {
                imageView.setImageResource(en_resid);
            }

            if (cn_resid == R.mipmap.guidepage_viewpage4) {
                clickOpen.setVisibility(View.VISIBLE);
                clickOpen.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        Intent in = new Intent(getBaseContext(), MainActivity2.class);
                        in.putExtra(MainActivity2.IsOnceCreate_label, true);
                        startActivity(in);
                        finish();

                    }
                });
            } else {
                clickOpen.setVisibility(View.GONE);
            }
        }

        public View getiPageView() {
            return iPageView;
        }
    }
}


 其实 说简单也简单,说难也难,看时候有这个经验和这个意识。还有良好的 知识储备和基础源码的理解。我就是哪一样的不占 。不过竟然还是在短时间内做出来了,还是值得我 得瑟一会的,毕竟 我i的师傅都说这个需要点时间来搞,有一点难度。


好了,暂且就先些这么多,等出差回来,有时间,在把自己觉得有意思的东西,总结下,记录下,万一有和我一样的菜鸟 遇到同样的问题呢,

最后BB 一句,我的大佬师傅说,一些效果能 自己写就自己去写,去研究,不要依赖第三方库,因为当APP 里面的内容大到一定程度的时候,你才考虑到代码的优化,或者出现内存的泄露,以及安装时候就出现             org.gradle.jvmargs=-Xmx4608M  不足,那时候在想着优化,重构就显得很麻烦 很耗费人力 ,精力了。

还有写代码的习惯一定要早早的养成,反正我觉得 多写点注释没毛病, 一是可以给 小白 用,二是 :可以让别人快速的阅读的你的代码,不会因为你某个 奇葩的 方法名字或者变量名字 想半天。 三是:以后你自己看的时候 更是能一下知道自己 以前 在哪里遇到坑了。问题的原因。


我就是废话比较多的那种人。谢谢观赏。


  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值