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



老规矩,先上效果图: Android中使用Lottie实现炫酷的引导页/介绍页
文章图片
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
【Android中使用Lottie实现炫酷的引导页/介绍页】关于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 positionViewPager当前页 * @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 generatePages(Bundle savedInstanceState) { final ArrayList 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的布局

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

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

Android中使用Lottie实现炫酷的引导页/介绍页
文章图片
lottie_guide.gif 【GitHub】项目代码

    推荐阅读