• app引导页(背景图片切换加各个页面动画效果)


    前言:不知不觉中又加班到了10点半,整个启动页面做了一天多的时间,一共有三个页面,每个页面都有动画效果,动画效果调试起来麻烦,既要跟ios统一,又要匹配各种不同的手机,然后产品经理还有可能在中途改需求,程序员各种苦逼有木有,在这个过程中也学到了蛮多东西的,所以写一篇博客跟大家分享一下.

     

    先看效果图:

    1.显示三个页面的Activity  用view pager去加载三个fragment实现,控制点点点的切换,监听view pager的切换,控制fragment动画的开始跟结束,重写了view pager,实现了背景图片的移动效果.

    [java] view plaincopy
     
    1. /** 
    2.  * 主Activity 
    3.  * @author ansen 
    4.  * @create time 2015-08-07 
    5.  */  
    6. public class KaKaLauncherActivity extends FragmentActivity {  
    7.     private GuideViewPager vPager;  
    8.     private List<LauncherBaseFragment> list = new ArrayList<LauncherBaseFragment>();  
    9.     private BaseFragmentAdapter adapter;  
    10.   
    11.     private ImageView[] tips;  
    12.     private int currentSelect;   
    13.       
    14.     @Override  
    15.     protected void onCreate(Bundle savedInstanceState) {  
    16.         super.onCreate(savedInstanceState);  
    17.         setContentView(R.layout.activity_luancher_main);  
    18.           
    19.         //初始化点点点控件  
    20.         ViewGroup group = (ViewGroup)findViewById(R.id.viewGroup);  
    21.         tips = new ImageView[3];  
    22.         for (int i = 0; i < tips.length; i++) {  
    23.             ImageView imageView = new ImageView(this);  
    24.             imageView.setLayoutParams(new LayoutParams(10, 10));  
    25.             if (i == 0) {  
    26.                 imageView.setBackgroundResource(R.drawable.page_indicator_focused);  
    27.             } else {  
    28.                 imageView.setBackgroundResource(R.drawable.page_indicator_unfocused);  
    29.             }  
    30.             tips[i]=imageView;  
    31.   
    32.             LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));  
    33.             layoutParams.leftMargin = 20;//设置点点点view的左边距  
    34.             layoutParams.rightMargin = 20;//设置点点点view的右边距  
    35.             group.addView(imageView,layoutParams);  
    36.         }  
    37.           
    38.         //获取自定义viewpager 然后设置背景图片  
    39.         vPager = (GuideViewPager) findViewById(R.id.viewpager_launcher);  
    40.         vPager.setBackGroud(BitmapFactory.decodeResource(getResources(),R.drawable.bg_kaka_launcher));  
    41.   
    42.         /** 
    43.          * 初始化三个fragment  并且添加到list中 
    44.          */  
    45.         RewardLauncherFragment rewardFragment = new RewardLauncherFragment();  
    46.         PrivateMessageLauncherFragment privateFragment = new PrivateMessageLauncherFragment();  
    47.         StereoscopicLauncherFragment stereoscopicFragment = new StereoscopicLauncherFragment();  
    48.         list.add(rewardFragment);  
    49.         list.add(privateFragment);  
    50.         list.add(stereoscopicFragment);  
    51.   
    52.         adapter = new BaseFragmentAdapter(getSupportFragmentManager(),list);  
    53.         vPager.setAdapter(adapter);  
    54.         vPager.setOffscreenPageLimit(2);  
    55.         vPager.setCurrentItem(0);  
    56.         vPager.setOnPageChangeListener(changeListener);  
    57.     }  
    58.       
    59.     /** 
    60.      * 监听viewpager的移动 
    61.      */  
    62.     OnPageChangeListener changeListener=new OnPageChangeListener() {  
    63.         @Override  
    64.         public void onPageSelected(int index) {  
    65.             setImageBackground(index);//改变点点点的切换效果  
    66.             LauncherBaseFragment fragment=list.get(index);  
    67.               
    68.             list.get(currentSelect).stopAnimation();//停止前一个页面的动画  
    69.             fragment.startAnimation();//开启当前页面的动画  
    70.               
    71.             currentSelect=index;  
    72.         }  
    73.           
    74.         @Override  
    75.         public void onPageScrolled(int arg0, float arg1, int arg2) {}  
    76.         @Override  
    77.         public void onPageScrollStateChanged(int arg0) {}  
    78.     };  
    79.       
    80.     /** 
    81.      * 改变点点点的切换效果 
    82.      * @param selectItems 
    83.      */  
    84.     private void setImageBackground(int selectItems) {  
    85.         for (int i = 0; i < tips.length; i++) {  
    86.             if (i == selectItems) {  
    87.                 tips[i].setBackgroundResource(R.drawable.page_indicator_focused);  
    88.             } else {  
    89.                 tips[i].setBackgroundResource(R.drawable.page_indicator_unfocused);  
    90.             }  
    91.         }  
    92.     }  
    93. }  


    2.重写viewpager   在dispatchDraw方法中控制显示的背景图片区域,

    [java] view plaincopy
     
    1. /** 
    2.  * 重写ViewPager  主要做一个切换背景的功能 
    3.  * @author ansen 
    4.  * @create time 2015-08-07 
    5.  */  
    6. public class GuideViewPager extends ViewPager {  
    7.     private Bitmap bg;  
    8.     private Paint b = new Paint(1);  
    9.       
    10.     public GuideViewPager(Context context) {  
    11.         super(context);  
    12.     }  
    13.   
    14.     public GuideViewPager(Context context, AttributeSet attrs) {  
    15.         super(context, attrs);  
    16.     }  
    17.   
    18.     @Override  
    19.     protected void dispatchDraw(Canvas canvas) {  
    20.         if (this.bg != null) {  
    21.             int width = this.bg.getWidth();  
    22.             int height = this.bg.getHeight();  
    23.             int count = getAdapter().getCount();  
    24.             int x = getScrollX();  
    25.             // 子View中背景图片需要显示的宽度,放大背景图或缩小背景图。  
    26.             int n = height * getWidth() / getHeight();  
    27.               
    28.             /** 
    29.              * (width - n) / (count - 1)表示除去显示第一个ViewPager页面用去的背景宽度,剩余的ViewPager需要显示的背景图片的宽度。 
    30.              * getWidth()等于ViewPager一个页面的宽度,即手机屏幕宽度。在该计算中可以理解为滑动一个ViewPager页面需要滑动的像素值。 
    31.              * ((width - n) / (count - 1)) /getWidth()也就表示ViewPager滑动一个像素时,背景图片滑动的宽度。 
    32.              * x * ((width - n) / (count - 1)) /  getWidth()也就表示ViewPager滑动x个像素时,背景图片滑动的宽度。 
    33.              * 背景图片滑动的宽度的宽度可以理解为背景图片滑动到达的位置。 
    34.              */  
    35.             int w = x * ((width - n) / (count - 1)) / getWidth();  
    36.             canvas.drawBitmap(this.bg, new Rect(w, 0, n + w, height), new Rect( x, 0, x + getWidth(), getHeight()), this.b);  
    37.         }  
    38.         super.dispatchDraw(canvas);  
    39.     }  
    40.       
    41.     public void setBackGroud(Bitmap paramBitmap) {  
    42.         this.bg = paramBitmap;  
    43.         this.b.setFilterBitmap(true);  
    44.     }  
    45. }  

    3.主体布局文件  上面放一个自定义的viewpager  下面放一个显示点点的RelativeLayout
    [html] view plaincopy
     
    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent" >  
    5.   
    6.     <com.example.view.GuideViewPager  
    7.         android:id="@+id/viewpager_launcher"  
    8.         android:layout_width="match_parent"  
    9.         android:layout_height="match_parent" />  
    10.   
    11.     <RelativeLayout  
    12.         android:layout_width="fill_parent"  
    13.         android:layout_height="wrap_content"  
    14.         android:orientation="vertical" >  
    15.   
    16.         <LinearLayout  
    17.             android:id="@+id/viewGroup"  
    18.             android:layout_width="fill_parent"  
    19.             android:layout_height="wrap_content"  
    20.             android:layout_alignParentBottom="true"  
    21.             android:layout_marginBottom="30dp"  
    22.             android:gravity="center_horizontal"  
    23.             android:orientation="horizontal" />  
    24.     </RelativeLayout>  
    25.   
    26. </RelativeLayout>  

    4.ViewPager适配器

    [java] view plaincopy
     
    1. /** 
    2.  * Viewpager适配器 
    3.  * @author apple 
    4.  * 
    5.  */  
    6. public class BaseFragmentAdapter extends FragmentStatePagerAdapter {  
    7.     private List<LauncherBaseFragment>list;  
    8.     public BaseFragmentAdapter(FragmentManager fm, List<LauncherBaseFragment> list) {  
    9.         super(fm);  
    10.         this.list = list;  
    11.     }  
    12.   
    13.     public BaseFragmentAdapter(FragmentManager fm) {  
    14.         super(fm);  
    15.     }  
    16.   
    17.     @Override  
    18.     public Fragment getItem(int arg0) {  
    19.         return list.get(arg0);  
    20.     }  
    21.   
    22.     @Override  
    23.     public int getCount() {  
    24.         return list.size();  
    25.     }  
    26. }  

    5.Fragment抽象类 有两个抽象方法,开启动画跟停止动画  所有的Fragment都继承这个类  Viewpager切换的时候可以更好的控制每个Fragment开启动画,结束动画

    [java] view plaincopy
     
    1. /** 
    2.  * Fragment抽象类 
    3.  * @author ansen 
    4.  *  
    5.  */  
    6. public abstract class LauncherBaseFragment extends Fragment{  
    7.     public abstract void  startAnimation();  
    8.     public abstract void  stopAnimation();  
    9. }  

    6.打赏页Fragment  三个动画效果  硬币向下移动动画+打赏图片缩放动画+改变打赏图片透明度然后隐藏图片

    [java] view plaincopy
     
    1. /** 
    2.  * 打赏页面 
    3.  * @author ansen 
    4.  * @create time 2015-08-07 
    5.  */  
    6. public class RewardLauncherFragment extends LauncherBaseFragment{  
    7.     private ImageView ivReward;  
    8.     private ImageView ivGold;  
    9.       
    10.     private Bitmap goldBitmap;  
    11.     private boolean started;//是否开启动画(ViewPage滑动时候给这个变量赋值)  
    12.       
    13.     @Override  
    14.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
    15.         View rooView=inflater.inflate(R.layout.fragment_reward_launcher, null);  
    16.         ivGold=(ImageView) rooView.findViewById(R.id.iv_gold);  
    17.         ivReward=(ImageView) rooView.findViewById(R.id.iv_reward);  
    18.           
    19.         //获取硬币的高度  
    20.         goldBitmap=BitmapFactory.decodeResource(getActivity().getResources(),R.drawable.icon_gold);  
    21.         startAnimation();  
    22.         return rooView;  
    23.     }  
    24.       
    25.     public void startAnimation(){  
    26.         started=true;  
    27.           
    28.         //向下移动动画 硬币的高度*2+80     
    29.         TranslateAnimation translateAnimation=new TranslateAnimation(0,0,0,goldBitmap.getHeight()*2+80);  
    30.         translateAnimation.setDuration(500);  
    31.         translateAnimation.setFillAfter(true);  
    32.           
    33.         ivGold.startAnimation(translateAnimation);  
    34.         translateAnimation.setAnimationListener(new AnimationListener() {  
    35.             @Override  
    36.             public void onAnimationStart(Animation animation) {}  
    37.             @Override  
    38.             public void onAnimationEnd(Animation animation){  
    39.                 if(started){  
    40.                     ivReward.setVisibility(View.VISIBLE);  
    41.                     //硬币移动动画结束开启缩放动画  
    42.                     Animation anim=AnimationUtils.loadAnimation(getActivity(),R.anim.reward_launcher);    
    43.                     ivReward.startAnimation(anim);  
    44.                     anim.setAnimationListener(new AnimationListener(){  
    45.                         @Override    
    46.                         public void onAnimationStart(Animation animation) {}    
    47.                         @Override    
    48.                         public void onAnimationRepeat(Animation animation) {}    
    49.                         @Override    
    50.                         public void onAnimationEnd(Animation animation) {  
    51.                                 //缩放动画结束 开启改变透明度动画  
    52.                                 AlphaAnimation alphaAnimation=new AlphaAnimation(1,0);  
    53.                                 alphaAnimation.setDuration(1000);  
    54.                                 ivReward.startAnimation(alphaAnimation);  
    55.                                 alphaAnimation.setAnimationListener(new AnimationListener() {  
    56.                                     @Override  
    57.                                     public void onAnimationStart(Animation animation) {}  
    58.                                     @Override  
    59.                                     public void onAnimationRepeat(Animation animation) {}  
    60.                                     @Override  
    61.                                     public void onAnimationEnd(Animation animation) {  
    62.                                         //透明度动画结束隐藏图片  
    63.                                         ivReward.setVisibility(View.GONE);  
    64.                                     }  
    65.                             });  
    66.                         }  
    67.                     });  
    68.                 }  
    69.             }  
    70.             @Override  
    71.             public void onAnimationRepeat(Animation animation) {}  
    72.         });  
    73.     }  
    74.       
    75.     @Override  
    76.     public void stopAnimation(){  
    77.         started=false;//结束动画时标示符设置为false  
    78.         ivGold.clearAnimation();//清空view上的动画  
    79.     }  
    80. }  

    7.私信页面   四个动画效果   并且四个动画都相同,其实只要我们实现了一个,其他的基本都很容易了.   依次实现四个图片的放大然后还原

    [java] view plaincopy
     
    1. /** 
    2.  * 私信 
    3.  * @author ansen 
    4.  */  
    5. public class PrivateMessageLauncherFragment extends LauncherBaseFragment{  
    6.     private ImageView ivLikeVideo,ivThinkReward,ivThisWeek,ivWatchMovie;  
    7.       
    8.     private Animation likeAnimation,thinkAnimation,watchAnimation,thisWeekAnimation;  
    9.       
    10.     private boolean started;//是否开启动画  
    11.       
    12.     @Override  
    13.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
    14.         View rooView=inflater.inflate(R.layout.fragment_private_message_launcher, null);  
    15.           
    16.         ivLikeVideo=(ImageView) rooView.findViewById(R.id.iv_private_message_like_video);  
    17.         ivThinkReward=(ImageView) rooView.findViewById(R.id.iv_private_message_think_reward);  
    18.         ivWatchMovie=(ImageView) rooView.findViewById(R.id.iv_private_message_watch_movie);  
    19.         ivThisWeek=(ImageView) rooView.findViewById(R.id.private_message_this_week);  
    20.         return rooView;  
    21.     }  
    22.       
    23.     public void stopAnimation(){  
    24.         //动画开启标示符设置成false     
    25.         started=false;  
    26.         /** 
    27.          * 清空所有控件上的动画 
    28.          */  
    29.         ivLikeVideo.clearAnimation();  
    30.         ivThinkReward.clearAnimation();  
    31.         ivWatchMovie.clearAnimation();  
    32.         ivThisWeek.clearAnimation();  
    33.     }  
    34.       
    35.       
    36.     public void startAnimation(){  
    37.         started=true;  
    38.           
    39.         /** 
    40.          * 每次开启动画前先隐藏控件 
    41.          */  
    42.         ivLikeVideo.setVisibility(View.GONE);  
    43.         ivThinkReward.setVisibility(View.GONE);  
    44.         ivWatchMovie.setVisibility(View.GONE);  
    45.         ivThisWeek.setVisibility(View.GONE);  
    46.           
    47.         new Handler().postDelayed(new Runnable() {//延时0.5秒之后开启喜欢视频动画  
    48.             @Override  
    49.             public void run(){  
    50.                 if(started)  
    51.                     likeVideoAnimation();  
    52.             }  
    53.         },500);  
    54.     }  
    55.       
    56.     /** 
    57.      * 好喜欢你的视频 
    58.      */  
    59.     private void likeVideoAnimation(){  
    60.         ivLikeVideo.setVisibility(View.VISIBLE);  
    61.           
    62.         likeAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  
    63.         ivLikeVideo.startAnimation(likeAnimation);//开启动画  
    64.         likeAnimation.setAnimationListener(new AnimationListener(){    
    65.             @Override    
    66.             public void onAnimationStart(Animation animation) {}    
    67.             @Override    
    68.             public void onAnimationRepeat(Animation animation) {}    
    69.             @Override    
    70.             public void onAnimationEnd(Animation animation) {//监听动画结束  
    71.                     if(started)  
    72.                         thinkReward();  
    73.             }    
    74.         });   
    75.     }  
    76.       
    77.     /** 
    78.      * 谢谢你的打赏 
    79.      */  
    80.     private void thinkReward(){  
    81.         ivThinkReward.setVisibility(View.VISIBLE);  
    82.         thinkAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  
    83.         ivThinkReward.startAnimation(thinkAnimation);  
    84.         thinkAnimation.setAnimationListener(new AnimationListener(){    
    85.             @Override    
    86.             public void onAnimationStart(Animation animation) {}    
    87.             @Override    
    88.             public void onAnimationRepeat(Animation animation) {}    
    89.             @Override    
    90.             public void onAnimationEnd(Animation animation) {  
    91.                 if(started)  
    92.                     watchMovie();  
    93.             }    
    94.         });   
    95.     }  
    96.       
    97.     /** 
    98.      * 一起看个电影呗 
    99.      */  
    100.     private void watchMovie(){  
    101.         ivWatchMovie.setVisibility(View.VISIBLE);  
    102.         watchAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  
    103.         ivWatchMovie.startAnimation(watchAnimation);  
    104.         watchAnimation.setAnimationListener(new AnimationListener(){    
    105.             @Override    
    106.             public void onAnimationStart(Animation animation) {}    
    107.             @Override    
    108.             public void onAnimationRepeat(Animation animation) {}    
    109.             @Override    
    110.             public void onAnimationEnd(Animation animation) {  
    111.                 if(started)  
    112.                     thisWeek();  
    113.             }    
    114.         });   
    115.     }  
    116.       
    117.     /** 
    118.      * 好啊  这周末有空 
    119.      */  
    120.     private void thisWeek(){  
    121.         ivThisWeek.setVisibility(View.VISIBLE);  
    122.         thisWeekAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);    
    123.         ivThisWeek.startAnimation(thisWeekAnimation);  
    124.     }  
    125. }  

    8.最后一个引导页  就两个动画  图片的放大跟缩小,其实用xml布局的话一个动画就能搞定,跟私信页面的动画差不多.小伙伴写的代码.这里换了一种方式.代码比较多.

    [java] view plaincopy
     
    1. /** 
    2.  * 最后一个 
    3.  * @author apple 
    4.  */  
    5. public class StereoscopicLauncherFragment extends LauncherBaseFragment implements OnClickListener{  
    6.     private static final float ZOOM_MAX = 1.3f;  
    7.     private static final  float ZOOM_MIN = 1.0f;  
    8.       
    9.     private ImageView imgView_immediate_experience;  
    10.       
    11.     @Override  
    12.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
    13.         View rooView=inflater.inflate(R.layout.fragment_stereoscopic_launcher, null);  
    14.         imgView_immediate_experience=(ImageView) rooView.findViewById(R.id.imgView_immediate_experience);  
    15.         imgView_immediate_experience.setOnClickListener(this);  
    16.         return rooView;  
    17.     }  
    18.       
    19.     public void playHeartbeatAnimation(){  
    20.             /** 
    21.              * 放大动画 
    22.              */  
    23.         AnimationSet animationSet = new AnimationSet(true);  
    24.         animationSet.addAnimation(new ScaleAnimation(ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, ZOOM_MAX, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f));  
    25.         animationSet.addAnimation(new AlphaAnimation(1.0f, 0.8f));  
    26.    
    27.         animationSet.setDuration(500);  
    28.         animationSet.setInterpolator(new AccelerateInterpolator());  
    29.         animationSet.setFillAfter(true);  
    30.    
    31.         animationSet.setAnimationListener(new AnimationListener() {  
    32.             @Override  
    33.             public void onAnimationStart(Animation animation) {  
    34.             }  
    35.    
    36.             @Override  
    37.             public void onAnimationRepeat(Animation animation) {  
    38.             }  
    39.    
    40.             @Override  
    41.             public void onAnimationEnd(Animation animation) {  
    42.                     /** 
    43.                      * 缩小动画 
    44.                      */  
    45.                 AnimationSet animationSet = new AnimationSet(true);  
    46.                 animationSet.addAnimation(new ScaleAnimation(ZOOM_MAX, ZOOM_MIN, ZOOM_MAX,ZOOM_MIN, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f));  
    47.                 animationSet.addAnimation(new AlphaAnimation(0.8f, 1.0f));  
    48.                 animationSet.setDuration(600);  
    49.                 animationSet.setInterpolator(new DecelerateInterpolator());  
    50.                 animationSet.setFillAfter(false);  
    51.                  // 实现心跳的View  
    52.                 imgView_immediate_experience.startAnimation(animationSet);  
    53.             }  
    54.         });  
    55.          // 实现心跳的View  
    56.         imgView_immediate_experience.startAnimation(animationSet);  
    57.     }   
    58.   
    59.     @Override  
    60.     public void onClick(View v) {  
    61. //      Intent intent = new Intent();  
    62. //      intent.setClass(getActivity(),MainActivity.class);  
    63. //      startActivity(intent);  
    64. //      getActivity().finish();  
    65.     }  
    66.   
    67.     @Override  
    68.     public void startAnimation() {  
    69.         playHeartbeatAnimation();  
    70.     }  
    71.   
    72.     @Override  
    73.     public void stopAnimation() {  
    74.           
    75.     }  
    76. }  

    最后总结:以上就是三个引导页的核心代码了,还有一些布局文件,动画效果的布局文件我就不一一贴出来的,大家可以去下载我的源码,在这个过程中碰到的几个大的问题说明一下.

    1.viewpager切换的时候要结束上个fragment的动画   我是通过boolean变量去控制的

    2.背景图片移动的效果    之前自己走了很多弯路,后面在网上找了一个demo拿过来用了.因为大家都有开源精神所以这里省了很多功夫

    3.图片放大缩小以前居然不知道一个xml动画布局就能搞定.之前一直想办法用两个动画实现

    看看时间一篇博客写了一个半小时,都12点了,办公室一个人敲打着键盘,记录着这两天做过的东西,才发现这也是一件很惬意的事情。。。。闪人。。。回家.
    推荐下自己创建的android QQ群:202928390 欢迎大家的加入.

    点击下载源码

    如果你想第一时间看我们的后期文章,扫码关注公众号,每个周末都会推送Android开发实战教程一篇,其余时间我们会推出一些互联网行业新闻,你还等什么,赶快关注吧,既能学到技术,还能长逼格,出任ceo,赢取白富美。。。。。 
    互联网动态

  • 相关阅读:
    sql 执行动态语句
    Cookie/Session机制详解
    .NET简谈事务、分布式事务处理
    .NET(C#)中不同级别的安全透明代码对类型的影响
    C#开发微信门户及应用(1)开始使用微信接口
    WIN7管理工具配置ODBC数据源系统DSN中无Oracle,Sybase驱动的解决方法
    题解 smoj 2806 【建筑物】
    题解 luogu P2568 GCD
    题解 luogu P1251 【餐巾计划问题】
    0377组合总和IV Marathon
  • 原文地址:https://www.cnblogs.com/yishaochu/p/5078577.html
Copyright © 2020-2023  润新知