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



    
    
    
    

    
    
    
    
    
    
    
   
    
        
        
        
        
        
        

    


主要的图片 贴下 

ViewPager之onPageScrolled的动画_第1张图片

ViewPager之onPageScrolled的动画_第2张图片


ViewPager之onPageScrolled的动画_第3张图片


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

问题就在于如果 很好的移动这些简单的布局 元素,然后 达到产品和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
 
  
/**
 * 

GDU pro guidepage 引导页

*/ 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; } /** *

viewpager 事件

*/ 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) { } }); } /** *

引导页 文字显示 的 渐变 出现和显示

* * @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); } } /** *

设置图片的Alpha

*/ 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); } } /** *

指示点 显示

* * @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); } } /** *

Viewpager 适配器

*/ 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  不足,那时候在想着优化,重构就显得很麻烦 很耗费人力 ,精力了。

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


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


你可能感兴趣的:(Android进阶)