Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MotionLayout Знакомство и применение

MOSDROID
November 10, 2018

MotionLayout Знакомство и применение

Павел Апановский, Сбертех – MOSDROID #13 Aluminium

На Google I/O '18 был представлен новый механизм работы с анимацией в Android - MotionLayout. Разберем, что он из себя представляет, как им пользоваться, что скрывается под капотом, да и нужен ли он в проекте?

MOSDROID

November 10, 2018
Tweet

More Decks by MOSDROID

Other Decks in Programming

Transcript

  1. Что ждет нас сегодня: - Знакомство с MotionLayout - MotionScene

    - Custom attributes - KeyFrames - MotionLayout и старые знакомые - Жизнь на глубине - Метрики, выводы !3
  2. Знакомство с MotionLayout «This Layout supports transitions between constraint sets

    defined in MotionScenes» «A MotionLayout is a ConstraintLayout which allows you to animate layouts between various states» min API 18 !6
  3. MotionScene <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/motion_view" android:layout_width="@dimen/size_big_x" android:layout_height="@dimen/size_big_x" android:layout_marginStart="@dimen/size_small" android:background="@color/colorAccent" motion:layout_constraintBottom_toBottomOf="parent"

    motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent"/> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/motion_view" android:layout_width="@dimen/size_big_x" android:layout_height="@dimen/size_big_x" android:layout_marginEnd="@dimen/size_small" android:background="@color/colorAccent" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent"/> </ConstraintSet> !13 MotionScene ConstraintSet
  4. Custom attributes <Transition motion:constraintSetEnd="@+id/end" motion:constraintSetStart="@+id/start" motion:duration="1000" motion:interpolator="linear"> motion:interpolator="linear" !15 <ConstraintSet

    android:id="@+id/start"> <Constraint <!—…—> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint <!—…—> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#9999FF" /> </Constraint> </ConstraintSet> MotionScene ConstraintSet CustomAttribute
  5. KeyFrames <KeyFrameSet> <KeyPosition motion:framePosition="30" motion:keyPositionType="parentRelative" motion:percentY="0.20" motion:target="@id/motion_view"/> <KeyPosition motion:framePosition="80" motion:keyPositionType="parentRelative"

    motion:percentY="0.70" motion:target="@id/motion_view"/> <KeyAttribute android:rotation="45" android:scaleX="1.3" android:scaleY="1.3" motion:framePosition="50" motion:target="@id/motion_view"/> </KeyFrameSet> !20 MotionScene Transition KeyFrameSet
  6. MotionLayout в гостях у CoordinatorLayout public class CollapsibleToolbar extends MotionLayout

    implements AppBarLayout.OnOffsetChangedListener { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { setProgress((float) -verticalOffset / appBarLayout.getTotalScrollRange()); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); ViewParent parent = this.getParent(); if (parent instanceof AppBarLayout) { ((AppBarLayout) parent) .addOnOffsetChangedListener(this); } } !22 setProgress((float) -verticalOffset / appBarLayout.getTotalScrollRange());
  7. MotionLayout в гостях у CoordinatorLayout <KeyFrameSet> <KeyPosition motion:framePosition="25" motion:keyPositionType="parentRelative" motion:percentY="1"

    motion:target="@id/icon_background" /> <KeyPosition motion:framePosition="25" motion:keyPositionType="parentRelative" motion:percentY="1" motion:target="@id/icon" /> </KeyFrameSet> !23
  8. MotionLayout в гостях у CoordinatorLayout <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/background" android:layout_width="match_parent"

    android:layout_height="match_parent" android:alpha="1.0" motion:layout_constraintBottom_toBottomOf="parent" /> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/background" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="0" motion:layout_constraintBottom_toBottomOf="parent" /> !24
  9. MotionLayout в гостях у ViewPager public class ViewPagerHeader extends MotionLayout

    implements ViewPager.OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { int numPages = 3; setProgress((position + positionOffset) / (numPages - 1)); } !26 setProgress((position + positionOffset) / (numPages - 1));
  10. MotionLayout в гостях у ViewPager <Constraint android:id="@id/item" android:layout_width="@dimen/size_big_x" android:layout_height="@dimen/size_big_x" android:layout_marginBottom="8dp"

    android:layout_marginLeft="20dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintLeft_toLeftOf="parent" /> </ConstraintSet> <Constraint android:id="@id/item" android:layout_width="@dimen/size_big_x" android:layout_height="@dimen/size_big_x" android:layout_marginBottom="8dp" android:layout_marginRight="20dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintRight_toRightOf="parent" /> </ConstraintSet> !27
  11. Жизнь на глубине private class DevModeDraw { private static final

    int DEBUG_PATH_TICKS_PER_MS = 16; float[] mPoints; int[] mPathMode; float[] mKeyFramePoints; public void draw(Canvas canvas, HashMap<View, MotionController> frameArrayList, int duration, int debugPath) { if (frameArrayList != null && frameArrayList.size() != 0) { canvas.save(); Iterator var5 = frameArrayList.values().iterator(); private void drawTicks(Canvas canvas, int mode, int keyFrames, MotionController motionController) { int viewWidth = 0; int viewHeight = 0; private void drawPathRelativeTicks(Canvas canvas, float x, float y) { float x1 = this.mPoints[0]; float y1 = this.mPoints[1]; private void drawPathCartesian(Canvas canvas) { float x1 = this.mPoints[0]; float y1 = this.mPoints[1]; private void drawPathCartesianTicks(Canvas canvas, float x, float y) { float x1 = this.mPoints[0]; float y1 = this.mPoints[1]; private void drawPathScreenTicks(Canvas canvas, float x, float y, int viewWidth, int viewHeight) { float x1 = 0.0F; float y1 = 0.0F; private void drawRectangle(Canvas canvas, MotionController motionController) { this.mPath.reset(); int rectFrames = 50; !28
  12. «While we are actively working on this tool, it’s not

    available yet. It will likely be available once the library reaches stable / beta» © Nicolas Roard !31 MotionLayout tools
  13. Выводы !32 Плюсы: • Мощный инструмент для работы с анимацией

    переключения сцен • Визуальный редактор • Min API 18 Минусы: • MotionLayout - alpha • Визуальный редактор - alpha