Android 项目实践(六)——开机动画的实现

  这几天项目也快结尾了,前几天一直忙着项目,博客也没怎么整理,这几天抓紧补一下。
  在5篇博客中已经讲解了项目开发的大部分,剩余的基本就是Coding了,在接下来几篇博客中,我将会挑取项目中的稍微复杂的页面讲解。

源码下载
  
  今天实现的是项目的开机动画。程序在安装后第一次打开时会有开机动画引导,这应该算是项目比较炫酷的一个地方,通过动画的形式向用户展现应用概览,更加人性化。

一、开机动画效果实现

这里写图片描述

、动画效果
1. 一共有4页。
2. 当滑动到该页时,动画才开始播放。
3. 当4页全部浏览完毕,在返回浏览时, 动画显示的是最终结果不再重新加载。

二、开机动画代码实现

  动画实现使用的是View Animation中简单的平移,旋转,透明度等,比较简单。因此不会再具体的讲解动画动作的实现,只讲解整体动画实现的大体思路。
  动画实现使用的ViewPager嵌套Fragmnet,在Fragment中实现动画的动作。这里在使用ViewPager时就涉及到了ViewPager的预加载问题。

1. Activity内容

以下是Activity的内容,先看代码,然后逐步分析:

public class WelcomePageActivity extends BaseActivity {
    private ViewPager mVeiwPager;//显示Fragment的ViewPager
    private List<Fragment> mFragments;//Fragment页面的集合
    private FragmentManager mManager;//Fragment的管理器。
    private FragmentPageOne mFragmentPageOne;
    private FragmentPageTwo mFragmentPageTwo;
    private FragmentPageThree mFragmentPageThree;
    private FragmentPageFour mFragmentPageFour;

    private WelcomePagePagerAdapter mAdapter;//ViewPager的适配器

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome_page);
        //ViewPager的对象
        mVeiwPager = (ViewPager) findViewById(R.id.viewpager_activity_welcome_page);
        //ViewPager中放置Fragment的集合
        mFragments = new ArrayList<>();
        mManager = getSupportFragmentManager();
        mFragmentPageOne = new FragmentPageOne();
        mFragmentPageTwo = new FragmentPageTwo();
        mFragmentPageThree = new FragmentPageThree();
        mFragmentPageFour = new FragmentPageFour();
        mFragments.add(mFragmentPageOne);
        mFragments.add(mFragmentPageTwo);
        mFragments.add(mFragmentPageThree);
        mFragments.add(mFragmentPageFour);
        mAdapter = new WelcomePagePagerAdapter(mManager,mFragments);
        mVeiwPager.setOffscreenPageLimit(4);//重要!  此处设置ViewPager的预加载为4页。
        mVeiwPager.setAdapter(mAdapter);//设置ViewPager的适配器
        mVeiwPager.setCurrentItem(0);//设置ViewPager开始的页面。
    }
}

Point One
  Activity中设置要显示的四个Fragment页面。
Point One
  ViewPager要设置预加载页面为4,通过方法:setOffscreenPageLimit(4)
  原因:由于我们要显示的是4个页面的动画,ViewPager有默认预加载的功能,默认为预加载一页,但是我们的动画是不允许预加载的,因为如果我们对VIewPager进行了预加载,如果预加载为2页,当我们翻到第一页动画的时候,第2页和第3页的动画也会同时加载,这并不是我们想要的,我们想要的是当翻到该页时该页的动画才开始播放。所以我们在Fragment中要避免预加载的使用。
  但是为什么这里我们还是要设置预加载的页面呢?原因是,在我们的第一页动画的Fragment中并没有定义不使用预加载功能,因此,当我们从最后一页往前翻页,翻到第一页是动画还是加载完成的样子,我们设置了ViewPager为4页。可能大家看到这还是有点晕,没关系,往下接着看,当看到“Fragment定义”时,便会明白了。

2. Fragment定义

  首先定义一个LauncherBaseFragment 抽象类,定义开始和停止动画两个方法,然后当定义四个Fragment动画页面时,继承这个抽象类:

public abstract class LauncherBaseFragment extends BaseFragment {
    public abstract void  startAnimation();
    public abstract void  stopAnimation();
}

(1). FragmentPageOne定义

public class FragmentPageOne extends LauncherBaseFragment {
    private View view;//该Fragment的值
    private boolean started;//是否开启动画(ViewPage滑动时候给这个变量赋值)

    private List<ImageView> mImageViews;//用于存储Image动画图片
    //以下是显示的ImageView,通过这些Image实现动画。
    private ImageView mImage1;
    private ImageView mImage2;
    private ImageView mImage3;
    private ImageView mImage4;
    private ImageView mImage5;
    private ImageView mImage6;
    private ImageView mImage7;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_setting_about_welcome_page1, null);//该Fragment的View
        mImage1 = (ImageView) view.findViewById(R.id.imageview1_activity_setting_about_welcome_page1);
        mImage2 = (ImageView) view.findViewById(R.id.imageview2_activity_setting_about_welcome_page1);
        mImage3 = (ImageView) view.findViewById(R.id.imageview3_activity_setting_about_welcome_page1);
        mImage4 = (ImageView) view.findViewById(R.id.imageview4_activity_setting_about_welcome_page1);
        mImage5 = (ImageView) view.findViewById(R.id.imageview5_activity_setting_about_welcome_page1);
        mImage6 = (ImageView) view.findViewById(R.id.imageview6_activity_setting_about_welcome_page1);
        mImage7 = (ImageView) view.findViewById(R.id.imageview7_activity_setting_about_welcome_page1);
        mImageViews = new ArrayList<>();
        mImageViews.add(mImage1);
        mImageViews.add(mImage2);
        mImageViews.add(mImage3);
        mImageViews.add(mImage4);
        mImageViews.add(mImage5);
        mImageViews.add(mImage6);
        mImageViews.add(mImage7);
        startAnimation();
        return view;
    }

    /**
     * 实现抽象父类LauncherBaseFragment的开始动画方法
     */
    @Override
    public void startAnimation() {
        started = true;
        //缩放动画
        if (started) {
            for (int i = 0; i < mImageViews.size(); i++) {
                mImageViews.get(i).setVisibility(View.VISIBLE);
                ScaleAnimation animationScale1 = new ScaleAnimation(0.0f, 1.2f, 0.0f, 1.2f);
                animationScale1.setDuration(800);//动画播放5秒
                mImageViews.get(i).startAnimation(animationScale1);
                final int finalI = i;
                animationScale1.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                    }
                    @Override
                    public void onAnimationEnd(Animation animation) {
                        ScaleAnimation animationScale2 = new ScaleAnimation(1.2f, 1f, 1.2f, 1f);
                        animationScale2.setDuration(200);//动画播放52秒
                        mImageViews.get(finalI).startAnimation(animationScale2);
                    }
                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }
                });
            }
        }
    }

    /**
     * 实现抽象父类LauncherBaseFragment结束动画的方法。
     */
    @Override
    public void stopAnimation() {
        started = false;
    }
}

Point One
  我们第1页动画实现的效果是:当打开应用时,第1页动画开始加载,当4页动画全部浏览完毕时,我们返回查看时,动画不再重新加载,直接显示最后的结果页面。也就是我们从第4页返回第1页时,第1页不再加载。
  
Point Two
  这一页代码比较简单。我们如果想要实现当返回滑动时,第1页不加载,我们就要去除ViewPager的预加载功能。但是在这里我们并没有去除预加载功能。
  原因是:我曾经尝试在第1页也去除预加载功能,但导致的结果就是这一页就不必再显示了。所以我们这里使用预加载4页来完成当返回查看时,显示第1页结果的功能。如果我们预加载的是4页,那么,当我们滑动到第4页时,其余的三页也都加载完毕了。

(2). FragmentPageTwo定义
先上代码:

public class FragmentPageTwo extends LauncherBaseFragment {
    private View view;
    private boolean started = true;//是否开启动画(ViewPage滑动时候给这个变量赋值)
    //执行动画的图片
    private ImageView mImage1;
    private ImageView mImage2;
    private ImageView mImage3;
    private ImageView mImage4;
    private ImageView mImage5;
    private ImageView mImage6;
    private ImageView mImage7;
    private ImageView mImage8;
    private ImageView mImage9;
    private ImageView mImage10;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if(view==null){
            view=inflater.inflate(R.layout.activity_setting_about_welcome_page2, null);
        }
        //缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null) {
            parent.removeView(view);
        }
        //获得执行动画的图片对象。
        mImage1 = (ImageView) view.findViewById(R.id.imageview1_activity_setting_about_welcome_page2);
        mImage2 = (ImageView) view.findViewById(R.id.imageview2_activity_setting_about_welcome_page2);
        mImage3 = (ImageView) view.findViewById(R.id.imageview3_activity_setting_about_welcome_page2);
        mImage4 = (ImageView) view.findViewById(R.id.imageview4_activity_setting_about_welcome_page2);
        mImage5 = (ImageView) view.findViewById(R.id.imageview5_activity_setting_about_welcome_page2);
        mImage6 = (ImageView) view.findViewById(R.id.imageview6_activity_setting_about_welcome_page2);
        mImage7 = (ImageView) view.findViewById(R.id.imageview7_activity_setting_about_welcome_page2);
        mImage8 = (ImageView) view.findViewById(R.id.imageview8_activity_setting_about_welcome_page2);
        mImage9 = (ImageView) view.findViewById(R.id.imageview9_activity_setting_about_welcome_page2);
        mImage10 = (ImageView) view.findViewById(R.id.imageview10_activity_setting_about_welcome_page2);
        return view;
    }
    @Override
    public void startAnimation() {
        if(started){
        //楼房的动画
        Bitmap bitmapImageShop = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wel2_shop);
        TranslateAnimation translateAnimationShop = new TranslateAnimation(0, 0, -bitmapImageShop.getHeight(), 0);
        translateAnimationShop.setDuration(500);//动画播放5秒
        mImage1.setVisibility(View.VISIBLE);
        mImage1.startAnimation(translateAnimationShop);
        translateAnimationShop.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }
            @Override
            public void onAnimationEnd(Animation animation) {
                //显示道路一
                mImage2.setVisibility(View.VISIBLE);
                //森林的动画
                Bitmap bitmapImageForest = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wel2_forest);
                TranslateAnimation translateAnimationForest = new TranslateAnimation(0, 0, -bitmapImageForest.getHeight(), 0);
                translateAnimationForest.setDuration(500);//动画播放5秒
                mImage3.setVisibility(View.VISIBLE);
                mImage3.startAnimation(translateAnimationForest);
                translateAnimationForest.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                    }
                    @Override
                    public void onAnimationEnd(Animation animation) {
                        //显示道路二
                        mImage4.setVisibility(View.VISIBLE);
                        //男孩的动画
                        Bitmap bitmapImageBoy = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wel2_boy);
                        TranslateAnimation translateAnimationBoy = new TranslateAnimation(-bitmapImageBoy.getWidth(), 0, 0, 0);
                        translateAnimationBoy.setDuration(500);//动画播放5秒
                        mImage5.setVisibility(View.VISIBLE);
                        mImage5.startAnimation(translateAnimationBoy);
                        translateAnimationBoy.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                //电脑的动画
                                Bitmap bitmapImageComputer = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wel2_computer);
                                AlphaAnimation alphaAnimationComputer = new AlphaAnimation(0.0f,1.0f);
                                alphaAnimationComputer.setDuration(200);//动画播放5秒
                                mImage6.setVisibility(View.VISIBLE);
                                mImage6.startAnimation(alphaAnimationComputer);
                                alphaAnimationComputer.setAnimationListener(new Animation.AnimationListener() {
                                    @Override
                                    public void onAnimationStart(Animation animation) {
                                    }
                                    @Override
                                    public void onAnimationEnd(Animation animation) {
                                        //显示道路三
                                        mImage7.setVisibility(View.VISIBLE);
                                        //药品的动画
                                        Bitmap bitmapImageInjection = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wel2_injection);
                                        TranslateAnimation translateAnimationInjection = new TranslateAnimation(bitmapImageInjection.getWidth(), 0, 0, 0);
                                        translateAnimationInjection.setDuration(500);//动画播放5秒
                                        mImage8.setVisibility(View.VISIBLE);
                                        mImage8.startAnimation(translateAnimationInjection);
                                        translateAnimationInjection.setAnimationListener(new Animation.AnimationListener() {
                                            @Override
                                            public void onAnimationStart(Animation animation) {
                                            }
                                            @Override
                                            public void onAnimationEnd(Animation animation) {
                                                mImage9.setVisibility(View.VISIBLE);
                                                Bitmap bitmapImageMoney = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wel2_money);
                                                AlphaAnimation alphaAnimationMoney = new AlphaAnimation(0.0f,1.0f);
                                                alphaAnimationMoney.setDuration(200);//动画播放5秒
                                                mImage10.setVisibility(View.VISIBLE);
                                                mImage10.startAnimation(alphaAnimationMoney);
                                            }
                                            @Override
                                            public void onAnimationRepeat(Animation animation) {
                                            }
                                        });
                                    }
                                    @Override
                                    public void onAnimationRepeat(Animation animation) {
                                    }
                                });
                            }
                            @Override
                            public void onAnimationRepeat(Animation animation) {
                            }
                        });
                    }
                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }
                });
            }
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
        }
    }

    @Override
    public void stopAnimation() {
        started = false;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        if (isVisibleToUser) {
            //fragment可见时加载数据
            startAnimation();
            stopAnimation();
        } else {
            //不可见时不执行操作
        }
        super.setUserVisibleHint(isVisibleToUser);
    }
}

Point
  为了实现当滑动到该页面时,页面动画才加载的效果,这里我们去除了预加载功能:
1.首先判断View是否已被加载,如果已加载,则先移除(这里只是为了防止view已存在parent而报错)。

        if(view==null){
            view=inflater.inflate(R.layout.activity_setting_about_welcome_page2, null);
        }
        //缓存的View需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个view已经有parent的错误。
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null) {
            parent.removeView(view);
        }

2.为了防止预加载,我们需要重写下面这个方法:

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        if (isVisibleToUser) {
            //fragment可见时加载数据
            startAnimation();//当Fragment可见时,执行动画,结束后执行停止动画方法。
            stopAnimation();
        } else {
            //不可见时不执行操作
        }
        super.setUserVisibleHint(isVisibleToUser);
    }

  接下来的两个页面FragmentPageThree和FragmentPageFour与FragmentPageTwo实现是相同的就是,startAnimation()方法中动画效果的实现是不同的。这里不再重复讲解。

源码下载

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小_爽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值