美文网首页android UI系列专题安卓开发资料整理Android
Android中使用Lottie实现炫酷的引导页/介绍页

Android中使用Lottie实现炫酷的引导页/介绍页

作者: 幸运儿云阳 | 来源:发表于2019-09-29 11:02 被阅读0次
    老规矩,先上效果图: lottie_guide.gif

    Lottie是什么?

    Lottie 是一套跨平台的完整解决方案,设计师只需要使用 After Effectes 设计出动画之后,使用 Lottic 提供的 Bodymovin 将设计好的动画导出成 JSON 格式,就可以直接运用在 iOS、Android 和 React Native之上,无需关心中间的实现细节。

    引用一下前辈的Blog地址,如有冒犯,立刻删除。

    站在 Android 开发的角度,聊聊 Airbnb 的 Lottie!!!

    Lottie开源库Github地址

    lottie-android

    关于Lottie在Android上的构建,及其使用

    Lottie Docs_Android

    关于Lottie的介绍及其简单使用上述资料已经足矣。
    今天我们要做的就是如何在Android中使用Lottie实现/打造炫酷的引导页/介绍页。

    主要就是ViewPager的页面监听与LottieAnimationView动画的联动,就是ViewPager从当前页面到下一页面,动画的进度。

    为了提高开发效率,使用SlidingIntroScreen快速构建引导页面。

    什么是SlidingIntroScreen呢?

    可以看我上一篇Blog

    使用SlidingIntroScreen快速创建引导页介绍页

    开始创建Module,编写代码。

    GuideActivity.java继承IntroActivity,实现IntroActivity的抽象方法。

    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.animation.Interpolator;
    import android.widget.Scroller;
    
    import androidx.fragment.app.Fragment;
    import androidx.viewpager.widget.ViewPager;
    
    import com.airbnb.lottie.LottieAnimationView;
    import com.matthewtamlin.sliding_intro_screen_library.buttons.IntroButton;
    import com.matthewtamlin.sliding_intro_screen_library.core.IntroActivity;
    import com.matthewtamlin.sliding_intro_screen_library.core.LockableViewPager;
    import com.yunyang.guidepageslidingintro.fragment.EmptyFragment;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Collection;
    
    public class GuideActivity extends IntroActivity {
    
        private float[] animationTimes = new float[]{0f, 0.3333f, 0.6666f, 1f, 1f};
    
        private LockableViewPager mLockableViewPager;
    
        private LottieAnimationView mLottieAnimationView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            setTheme(R.style.NoActionBar);
            super.onCreate(savedInstanceState);
            View view = LayoutInflater.from(this).inflate(R.layout.activity_guide, null);
            mLottieAnimationView = (LottieAnimationView) view.findViewById(R.id.animation_view);
            getRootView().addView(mLottieAnimationView, 0);
            mLockableViewPager = (LockableViewPager) findViewById(R.id.intro_activity_viewPager);
            hideStatusBar();
            setViewPagerScroller();
            initEvent();
        }
    
        // ViewPager页面监听
        private void initEvent() {
            mLockableViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    setAnimationProgress(position, positionOffset);
                }
    
                @Override
                public void onPageSelected(int position) {
    
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
        }
    
        /**
         * 动画运行与ViewPager联动
         *
         * @param position       ViewPager当前页
         * @param positionOffset ViewPager下一页
         */
        private void setAnimationProgress(int position, float positionOffset) {
            float startProgress = animationTimes[position];
            float endProgress = animationTimes[position + 1];
            mLottieAnimationView.setProgress(Lerp(startProgress, endProgress, positionOffset));
        }
    
        /**
         * 可以用于物体到达另外一个目标物体之间进行平滑过渡运动效果
         *
         * @param start 开始位置
         * @param end   结束位置
         * @param t     [0,1]
         */
        private float Lerp(float start, float end, float t) {
            return start + t * (end - start);
        }
    
        /**
         * 使用反射操作ViewPagerScroller
         */
        private void setViewPagerScroller() {
            try {
                Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
                scrollerField.setAccessible(true);
                Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
                interpolator.setAccessible(true);
                Scroller mScroller = new Scroller(this, (Interpolator) interpolator.get(null)) {
                    @Override
                    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
                        super.startScroll(startX, startY, dx, dy, duration * 7);
                    }
                };
                scrollerField.set(mLockableViewPager, mScroller);
            } catch (NoSuchFieldException e) {
                // Do nothing.
            } catch (IllegalAccessException e) {
                // Do nothing.
            }
        }
    
        // SlidingIntroScreen中IntroActivity的抽象方法_生成活动页面
        @Override
        protected Collection<? extends Fragment> generatePages(Bundle savedInstanceState) {
            final ArrayList<Fragment> pages = new ArrayList<>();
            pages.add(EmptyFragment.newInstance());
            pages.add(EmptyFragment.newInstance());
            pages.add(EmptyFragment.newInstance());
            pages.add(EmptyFragment.newInstance());
            return pages;
        }
    
        // SlidingIntroScreen中IntroActivity的抽象方法_按钮行为
        @Override
        protected IntroButton.Behaviour generateFinalButtonBehaviour() {
            return new IntroButton.Behaviour() {
                @Override
                public void setActivity(IntroActivity activity) {
                    finish();
                }
    
                @Override
                public IntroActivity getActivity() {
                    return null;
                }
    
                @Override
                public void run() {
    
                }
            };
        }
    
    }
    

    该Activity的布局

    <?xml version="1.0" encoding="utf-8"?>
    <com.airbnb.lottie.LottieAnimationView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/animation_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        app:lottie_rawRes="@raw/walkthrough" />
    

    walkthrough.json(动画文件)文件放于Module下src/main/res/raw文件夹下。

    该Activity中EmptyFragment.java

    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    
    import com.yunyang.guidepageslidingintro.R;
    
    /**
     * Created by YunYang.
     * Date: 2019/9/28
     * Time: 13:21
     * Des: ViewPager+Fragment
     */
    public class EmptyFragment extends Fragment {
    
        public EmptyFragment() {
        }
    
        public static EmptyFragment newInstance() {
            EmptyFragment fragment = new EmptyFragment();
            Bundle args = new Bundle();
            fragment.setArguments(args);
            return fragment;
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_empty_vp, container, false);
        }
    
    }
    

    fragment_empty_vp.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
    </FrameLayout>
    

    代码量很少,效率高。(还是懒的好哦(- 、-))

    运行效果图:


    lottie_guide.gif

    【GitHub】项目代码

    相关文章

      网友评论

        本文标题:Android中使用Lottie实现炫酷的引导页/介绍页

        本文链接:https://www.haomeiwen.com/subject/dicfpctx.html