ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
Georgiy Shur: Bring onboarding to life
GEORGIY SHUR
Android Developer, Ackee
Bring onboarding to life
with ViewPager-based animations
Onboarding techniques
¡ñ Walkthroughs and tours
¡ñ Contextual tips and tutorials
¡ñ Empty states
¡ñ Dummy data, chatbots, etc....
Onboarding techniques
¡ñ Walkthroughs and tours
¡ñ Contextual tips and tutorials
¡ñ Empty states
¡ñ Dummy data, chatbots, etc....
Onboarding techniques
¡ñ Walkthroughs and tours
¡ñ Contextual tips and tutorials
¡ñ Empty states
¡ñ Dummy data, chatbots, etc....
Onboarding techniques
¡ñ Walkthroughs and tours
¡ñ Contextual tips and tutorials
¡ñ Empty states
¡ñ Dummy data, chatbots, etc....
Onboarding techniques
¡ñ Walkthroughs and tours
¡ñ Contextual tips and tutorials
¡ñ Empty states
¡ñ Dummy data, chatbots, etc....
Onboarding techniques
¡ñ Walkthroughs and tours
¡ñ Contextual tips and tutorials
¡ñ Empty states
¡ñ Dummy data, chatbots, etc....
Static screens are boring?
¡ñ Animated
¡ñ Interactive
ViewPager-based animations
concept
¡ñ Offset between pages
ViewPager-based animations
concept
¡ñ Offset between pages
¡ñ Parameter to animate (position, scale, color, ¡­)
ViewPager-based animations
concept
¡ñ Offset between pages
¡ñ Parameter to animate (position, scale, color, ¡­)
¡ñ Relation between them (linear, ¡­)
ViewPager-based animations
concept
¡ñ Offset between pages
¡ñ Parameter to animate (position, scale, color, ¡­)
¡ñ Relation between them (linear, ¡­)
¡ñ Pages involved
Between pages 1 and 2 I want to change x
position of view with relation x = offset/2
Parameters to animate
¡ñ Position (translation)
¡ñ Angle (rotation)
¡ñ Scale (size)
¡ñ Color
¡ñ Alpha (fade in/out)
¡ñ Progress (GIF, Lottie view)
¡ñ Custom, ...
Georgiy Shur: Bring onboarding to life
private void initHandWithPhone() {
ImageView hand = (ImageView) LayoutInflater. from(mPagerLayout.getContext())
.inflate(R.layout. decor_hand_with_phone, mPagerLayout, false);
Decor handDecor = new Decor.Builder(hand).setPage(Page. pageRange(2, 3))
.behindViewPage().withLayer().build();
RotationAnimation handRotateInAnim = new RotationAnimation(Page. singlePage(2), 30, 0);
handRotateInAnim.setInterpolator( new DecelerateInterpolator());
TranslationAnimation handMoveInAnim = new TranslationAnimation(Page. singlePage(2),
mCircleRadius + hand.getDrawable().getIntrinsicWidth() / 2,
-UiUtils. dpToPx(this, 16), UiUtils. dpToPx(this, 28), 0, true);
handMoveInAnim.setInterpolator( new DecelerateInterpolator());
RotationAnimation handRotateOutAnim = new RotationAnimation(Page. singlePage(3), 0, -60);
TranslationAnimation handMoveOutAnim = new TranslationAnimation(Page. singlePage(3),
UiUtils. dpToPx(this, 28), 0,
- mCircleRadius - hand.getDrawable().getIntrinsicWidth() / 2,
UiUtils. dpToPx(this, 166), true);
mSparkleMotion.animate(handRotateInAnim).animate(handMoveInAnim)
.animate(handRotateOutAnim).animate(handMoveOutAnim).on(handDecor);
}
ImageView hand = (ImageView) LayoutInflater
.from(mPagerLayout.getContext())
.inflate(R.layout.decor_hand_with_phone,
mPagerLayout, false);
Decor handDecor = new Decor.Builder(hand)
.setPage(Page.pageRange(2, 3))
.behindViewPage().withLayer().build();
RotationAnimation handRotateInAnim = new
RotationAnimation(Page.singlePage(2), 30, 0);
handRotateInAnim.setInterpolator(new DecelerateInterpolator());
TranslationAnimation handMoveInAnim = new TranslationAnimation(
Page.singlePage(2), mCircleRadius +
hand.getDrawable().getIntrinsicWidth() / 2,
-UiUtils.dpToPx(this, 16),
UiUtils.dpToPx(this, 28), 0, true);
handMoveInAnim.setInterpolator(new DecelerateInterpolator());
RotationAnimation handRotateOutAnim = new
RotationAnimation(Page.singlePage(3), 0, -60);
TranslationAnimation handMoveOutAnim = new
TranslationAnimation(Page.singlePage(3),
UiUtils.dpToPx(this, 28), 0, -mCircleRadius -
hand.getDrawable().getIntrinsicWidth() / 2,
UiUtils.dpToPx(this, 166), true);
mSparkleMotion
.animate(handRotateInAnim)
.animate(handMoveInAnim)
.animate(handRotateOutAnim)
.animate(handMoveOutAnim)
.on(handDecor);
class CustomPageTransformer : ViewPager.PageTransformer {
override fun transformPage(view: View, position: Float) {
with(view.find<Button>(R.id.btn_first)) {
alpha = position
translationX = -(1 - position) * 1.4f * view.width
}
with(view.find<Button>(R.id.btn_second)) {
alpha = position
translationX = -(1 - position) * 1.6f * view.width
}
}
}
val spritz = Spritz
.with(lottieAnimationView)
.withSteps(
SpritzStep.Builder()
.withAutoPlayDuration(500, TimeUnit.MILLISECONDS)
.withSwipeDuration(500, TimeUnit.MILLISECONDS)
.build(),
SpritzStep.Builder()
.withAutoPlayDuration(500, TimeUnit.MILLISECONDS)
.withSwipeDuration(500, TimeUnit.MILLISECONDS)
.build(),
SpritzStep.Builder()
.withAutoPlayDuration(500, TimeUnit.MILLISECONDS)
.build()
)
.build()
override fun onStart() {
super.onStart()
spritz.attachTo(viewPager)
spritz.startPendingAnimations()
}
override fun onStop() {
spritz.detachFrom(viewPager)
super.onStop()
}
https://github.com/IFTTT/SparkleMotion
https://developer.android.com/reference/android/support/v4/view/ViewPager.
PageTransformer.html
https://github.com/novoda/android-demos/tree/master/spritz
WWW.MDEVTALK.CZ
mdevtalk

More Related Content

Georgiy Shur: Bring onboarding to life