جشنواره فطر سون لرن

آموزش ساخت انیمیشن در اندروید استودیو با motionlayout

دسته بندی: اندروید
سطح مقاله: ساده
زمان مطالعه: 23 دقیقه
۲۸ اردیبهشت ۱۳۹۹

در این مقاله در مورد کلیات چگونگی ساخت انیمیشن در اندروید صحبت می‌کنیم. در مورد کاربردها و چگونگی ایجاد MotionScene  و اجزای آن صحبت کرده و همچنین یک نمونه بسیار ساده استفاده از آن را انجام خواهیم داد.در ادامه به ویژگی‌های موشن‌ لایوت (motionlayout) می‌پردازیم و انیمیشن‌های  جذابی را مثال می‌زنیم،و با نحوه‌ی ساخت ترکیبی انیمیشن‌ها با استفاده از موشن‌ لایوت آشنا می‌شوید.

فهرست محتوای این مقاله

انیمیشن در رابط کاربری

انیمیشن‌ها راهی عالی برای بهبود تجربه‌ی کاربری در نرم‌افزار هستند. از آنها جهت نمایش تغییرات و جلب توجه کاربر و ساخت صفحات زیبا استفاده می‌شود. انیمیشن ابزاری قدرتمند است که به کاربران نرم افزار شما کمک می‌کند بتوانند، حتی بخش‌های بسیار پیچیده و سنگین نرم افزار شما را بهتر درک کنند. جابجایی و حرکت بین وضعیت‌های مختلف به کاربر اجازه می‌دهد تا به طور طبیعی تغییرات در رابط کاربری  شما(UI) را ردیابی کند.

شما می‌توانید از انیمیشن‌ها برای جلب توجه عناصر مهم طرح‌تان استفاده کنید، زیرا حرکات موثر در طراحی باعث می‌شود برنامه‌ی شما پر زرق و برق به نظر برسد. برای مثال زمانی که یک لیست دارید و یک آیتم از آن تغییری می‌کند، متحرک سازی آن تغییر می‌تواند به کاربر برای درک بهتر آنچه اتفاق افتاده است کمک کند. یا وقتی تغییراتی در جابجایی از یک صفحه به صفحه دیگری دارید، انیمیشن‌ها می‌توانند به کاربر کمک کند که اشیاء ثابت و اشیایی که دچار تغییر شده‌اند را بهتر درک کند.

MotionLayout چیست؟

Android امکانات بسیاری را برای متحرک سازی اشیا UI فراهم می‌کند. و یکی از قوی‌ترین این ابزار جهت ساخت انیمیشن در اندروید که در سال 2018 توسط شرکت گوگل معرفی شده MotionLayout است. موشن‌ لایوت ترکیبی از ویژگی‌های فریم‌ ورک انیمیشن ، TransitionManager و CoordinatorLayout را ارائه می‌دهد.

MotionLayout یک بخش از کتابخانه ConstraintLayout است که در نسخه دوم این کتابخانه معرفی شد. و به شما این امکان را می‌دهد که انیمیشن‌هایی قوی  را به نرم افزار اندروید خود اضافه کنید. موشن‌ لایوت مبتنی بر ConstraintLayout است و شما می‌توانید هر چیزی که با استفاده از ConstraintLayout ساخته‌اید را متحرک کنید.

با موشن‌‌ لایوت قادر به متحرک کردن هرکدام از المان‌های طرحتان در همان بخش xml پروژه‌تان هستید.شما قادرید برای محل قرارگیری آن المان در صفحه (location)، اندازه آن (size)، وضعیت نمایش آن (visibility)، رنگ و سایر ویژگی‌هایش، انیمیشن دلخواهتان را اعمال کنید. همچنین می‌توانید اینکار را برای  چندین المان به طور همزمان انجام دهید، که پیاده سازی آن با استفاده از روش‌های دیگر انیمیشن بسیار سخت و پیچیده خواهد بود. در این مقاله با اصول اولیه‌ی موشن‌ لایوت و نحوه‌ی استفاده از آن برای ساخت انیمیشن‌های غنی در برنامه‌ی خود آشنا می‌شوید.

نحوه‌ی استفاده از MotionLayout

در ادامه نحوه‌ی استفاده از MotionLayout را برای ساخت انیمیشن در اندروید توضیح می‌دهیم.

مطابق این ویدیو ما قصد داریم طرحی را پیاده‌ سازی کنیم که در آن یک المان تعریف شده است و با لمس و حرکت آن به سمت چپ و راست این المان در کل طرح جابجا شود. برای پیاده سازی این انیمیشن مراحل زیر را دنبال می‌کنیم.

مرحله‌ی اول: افزودن کتابخانه‌ی ConstraintLayout به پروژه

همان‌طور که گفتیم موشن‌ لایوت یک زیر‌کلاس (subclass) از کانستریت‌لایوت (ConstraintLayout) است و برای استفاده از آن باید کتابخانه‌ی کانستریت‌لایوت (نسخه 2 به بالا) را به پروژه‌ی خود بیفزایید.

dependencies {
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
}

 

مرحله‌ی دوم: ایجاد یک فایل MotionLayout

در دومین گام شما باید برای طرح‌تان یک فایل لایوت از جنس موشن‌ لایوت ایجاد کنید. از آنجا که موشن‌ لایوت تمام ویژگی‌ها و امکانات کانستریت‌لایوت (ConstraintLayout) را برای شما فراهم می‌کند، پس می‌توانید با خیال راحت طرح‌های کانستریت‌لایوت (ConstraintLayout) خود را به موشن‌ لایوت تبدیل کنید.

برای پیاده‌ سازی طرح شکل1 فایلی با نام activity_main.xml را در پوشه‌ی لایوت ایجاد می‌کنیم و کدهای زیر را در آن می‌نویسیم:

<?xml version="1.0" encoding="utf-8"?>
<!-- activity_main.xml -->
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:id="@+id/motionLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_01"
    tools:showPaths="true">

    <View
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:background="@color/colorAccent"
        android:text="Button" />

</androidx.constraintlayout.motion.widget.MotionLayout>

 

مرحله‌ی سوم: ایجاد یک MotionScene

MotionScene یک فایل XML شامل تمامی جزییات متغیر برای لایوت مربوطه است و برای اینکه بتوانید اطلاعات و جزییات ثابت طرح خود را از جزییات متغیر تفکیک کنید برای هر موشن‌ لایوت یک MotionScene مربوط به خودش را تعریف کنید. در ادامه مراحل بالا اکنون یک فایل با نام scene_01 در پوشه‌ی xml  ایجاد می‌کنیم  (اگر پوشه‌ی xml در پروژه‌تان وجود ندارد آن را ایجاد کنید) و کدهای زیر را در آن قرار می‌دهیم .

در فایل activity_main که در مرحله‌ی قبل آن را ایجاد کردیم با کد "app:layoutDescription="@xml/scene_01 در واقع scene_01 را به آن ارجاع داده‌ایم.

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:motion="https://schemas.android.com/apk/res-auto">

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            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/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />
    </Transition>

</MotionScene>

برای درک بهتر کدهای بالا به تفکیک بخش‌های مختلف آن‌ را به صورت جداگانه بررسی می‌کنیم:

تعریف ConstraintSet

<ConstraintSet> یکی از بخش‌های اصلی یک MotionScene است و در آن محدودیت‌های المان‌های متحرک طرح را تعریف می‌کنیم. از آنجایی که هر جابجایی (انیمیشن) حداقل یک نقطه آغاز و یک نقطه پایان دارد برای هر یک از این حالات یک ConstraintSet جداگانه تعریف می‌کنیم. در داخل این ConstraintSetها نیز برای هر یک از این المان‌های متحرک فارغ از نوع آن در یک تگ جداگانه <Constraint> تعریف می‌کنیم و محدودیت‌های آن المان در آن تعریف می‌شود.

در کدهای بالا دو ConstraintSet تعریف شده است. یکی برای نقطه‌ی شروع انیمیشن و دیگری برای تعریف مشخصات نقطه‌ی پایانی انیمیشن و در هر کدام به طور جداگانه محدودیت‌های المان تعریف شده است. در ConstraintSet نقطه‌ی شروع المان در سمت چپ لایوت و در ConstraintSet نقطه‌ی پایانی در سمت راست لایوت قرار می‌گیرد.

تعریف Transition

در تگ <Transition> تمام تعاریف اصلی این انیمیشن را مشخص می‌کنیم:

  •  تعریف نقاط آغازین و پایانی: به طور معمول ، یک <Transition> به دو ConstraintSet اشاره می‌کند ، یکی شروع انیمیشن و دیگری انتهای آن را مشخص می‌کند. برای اینکه نقاط آغازی و پایانی یک انیمیشن را مشخص کنیم از کدهای motion:constraintSetStart و motion:constraintSetEnd استفاده می‌کنیم.
  • تعریف مدت زمان جابجایی: برای مشخص شدن مدت زمان این انیمیشن از motion:duration استفاده می‌کنیم.
  •  تعریف نوع محرک انیمیشن: در موشن‌ لایوت می‌توان تعریف کرد که چه نوع رفتاری از کاربر (یا وقوع حالت خاصی در نرم‌افزار) عامل محرک بروز انیمیشن مورد نظر شود.

<OnSwipe>

با تعریف سه مورد touchAnchorId و touchAnchorSide و dragDirection این تگ مشخص می‌کند که هنگام لمس و حرکت (swipe) یک المان خاص توسط کاربر چه نوع اکشنی در طرح رخ بدهد.

با مشخص کردن touchAnchorId می‌توان مشخص کرد با لمس کدام المان انیمیشن انجام می‌شود. و touchAnchorSide مشخص می‌کند جهت حرکت محرک از کدام سمت شروع می‌شود. و در نهایت با dragDirection می‌توان مشخص کرد جهت انیمیشن به کدام سمت است.

<OnClick>

این تگ نیز همانند تگ OnSwipe مشخص کننده‌ی نوع محرک انیمیشن است، ولی با این تفاوت که محرک شروع یک انیمیشن کلیک روی المان مورد نظر است. (در قسمت دوم مقاله بیشتر به آن می‌پردازیم)

نکات مهم

نکته1: اساسی‌ترین تفاوت موشن‌ لایوت و کانستریت‌ لایوت این است که، در موشن‌ لایوت ویژگی‌ها و صفات متحرک ویوهای طرح‌مان که قرار است با انیمیشن تغییر کنند  نیازی نیست در لایوت تعریف شوند. (در صورت تعریف شدن خطایی رخ نمی‌دهد و فقط از آنها چشم پوشی می‌شود) در این روش فقط آن دسته از ویژگی‌های المان‌ها که قرار نیست انیمیشنی روی آن‌ها اعمال شود را در فایل لایوت تعریف کنید. و بقیه کدهایتان را در MotionScene تعریف کنید.

نکته 2: موشن‌ لایوت فقط می‌تواند با المان‌های مستقیمش کار کند و نمی‌توانید به المان‌های غیر مستقیم (در صورت استفاده از لایه‌های تو در تو) جداگانه انیمیشنی اعمال کنید.

ویژگی‌های قابل تغییر(Interpolated attributes)

علاوه بر محدودیت‌های موقعیت و مرزهای یک المان، در یک فایل MotionScene، می‌توان خصوصیات دیگری را برای المان‌های متغیر  در طول انیمیشن تغییر داد. ویژگی‌های زیر توسط MotionScene قابل تغییر هستند:

  • alpha
  • visibility
  • elevation
  • rotation, rotationX, rotationY
  • translationX, translationY, translationZ
  • scaleX, scaleY

ویژگی‌های سفارشی (CustomAttribute)

اگر بخواهید علاوه بر صفاتی که به آن‌ها اشاره کردیم صفات دیگری از یک المان را در یک انیمیشن تغییر بدهید، می‌توانید در <Constraint> مربوط به آن المان یک <CustomAttribute> تعریف کنید و مقدار دلخواه خود را برای آن صفت برای هر یک از نقاط آغازی و پایانی انیمیشن تعریف کنید.

نکته: توجه کنید که Custom Attribute باید برای تمامی نقاط آغازی و پایانی انیمیشن تعریف شود.

برای تعریف یک ویژگی سفارشی باید motion:attributeName و motion:customColorValue برای آن تعریف شود. motion:attributeName مشخص می‌کند که کدام صفت (Attribute) از المان تغییر می‌کند و motion: customColorValue مقدار مشخص شده برای آن نقطه را مشخص می‌کند. برای تعریف یک ویژگی سفارشی برای ساخت انیمیشن در اندروید، می‌توانید یکی از صفات زیر را استفاده کنید:

  • برای رنگ‌ها motion:customColorValue
  •  برای اعداد motion:customIntegerValue
  • برای مقادیر اعشاری motion:customFloatValue
  • برای متون motion:customStringValue
  • برای اندازه‌ها motion:customDimension
  • برای مقادیر بولین motion:customBoolean

برای مثال می‌خواهیم مطابق این ویدیو، علاوه بر جابجایی، المان رنگ آن را نیز تغییر بدهیم. برای انجام این کار یک <Constraint> به هر یک از ConstraintSet‌های آغازین و پایانی مشابه آنچه در پایین مشاهده می‌کنید، اضافه می‌کنیم.

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginStart="8dp"
        motion:layout_constraintBottom_toBottomOf="parent"
        motion:layout_constraintStart_toStartOf="parent"
        motion:layout_constraintTop_toTopOf="parent">
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#D81B60" />
    </Constraint>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginEnd="8dp"
        motion:layout_constraintBottom_toBottomOf="parent"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintTop_toTopOf="parent">
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#9999FF" />
    </Constraint>
</ConstraintSet>

 

نقاط کلیدی (Keyframes):

در ابتدا دیدیم که برای ساخت انیمیشن در اندروید با موش لایوت باید صفات هر المان را در نقطه‌ی شروع و نقطه‌ی پایان انیمیشن مشخص کنیم. المان در طول اجرای انیمیشن، از نقطه‌ی شروع در یک مسیر خطی حرکت می‌کند و به نقطه‌ی پایان می‌رسد. حال اگر بخواهیم حرکت المان را از حالت خطی خارج کنیم و مسیری سفارشی به آن بدهیم یا در میانه‌ی راه ویژگی خاصی از المان( مثل رنگ و اندازه و...) را تغییر بدهیم، باید از Keyframeها استفاده کنیم.

ساخت انیمیشن در اندروید

کی فریم‌ها انواع مختلفی دارند که در بعضی ویژگی‌ها با هم مشترک هستند. با وجود این اشتراکات هر کدام ویژگی‌ها و رفتارهای خاص خود را هم دارند. در ادامه‌ی مقاله به معرفی و بررسی هر یک از آنها خواهیم پرداخت. انواع کی فریم (keyframe) عبارت‌اند از:

  • KeyPosition: کی‌ فریم موقعیت (Position keyframe)
  • KeyAttribute: کی فریم صفات (Attribute keyframe)
  • KeyCycle: کی‌ فریم چرخه (Cycle keyframe)
  • KeyTimeCycle: کی‌ فریم چرخه‌ی زمان (TimeCycle keyframe)

توجه داشته باشید که هر کدام از کی فریم‌ها از سایرین مستقل است. یعنی اگر می‌خواهید در یک نقطه خاص کی فریمی تعریف کنید، لازم نیست همه‌ی آنها را تعریف کنید.

ویژگی‌های مشترک کی‌ فریم‌ها:

ابتدا قبل از بررسی انواع کی فریم‌ها (موقعیت ، ویژگی ، چرخه ، چرخه زمان) به بررسی ویژگی‌های مشترک آنها می‌پردازیم : framePosition: زمانی که این ویژگی را برای کی فریم مشخص می‌کنیم باید عددی بین 0 تا 100 را برای آن تعیین کنیم. و در واقع تعیین می‌کنیم کی فریم ما، در چه زمانی از اجرای انیمیشن (بر حسب درصد) باید اعمال شود. target: با تعریف هدف (target) مشخص می‌کنیم که این کی فریم روی کدام المان در طرح‌مان باید اعمال شود. transitionEasing: در حالت پیش‌فرض حرکت بین نقاط به‌صورت خطی است. حال اگر بخواهیم این جابجایی به صورت منحنی باشد از transitionEasing استفاده می‌کنیم.

کی‌ فریم موقعیت (Position keyframe):

در بین انواع کی فریم‌ها، رایج‌ترین نوع کی فریم موقعیت است که به شما امکان می‌دهد مسیری را که المان در طول انتقال روی صفحه نمایش طی می‌کند را تغییر دهید. در ادامه‌ی مقاله‌ی ساخت انیمیشن در اندروید به توضیح کی فریم موقعیت می‌پردازیم.

به عنوان مثال، در قسمت اول طرحی را پیاده کردیم که در آن یک المان از سمت چپ به سمت راست حرکت می‌کرد. حال می‌خواهیم مطابق ویدیو بالا، حرکت این جابجایی را از حالت خطی خارج کنیم و المان به صورت منحنی حرکت کند و زمانی که به وسط جابجایی (50درصد) رسید ارتفاع آن به میزان یک چهارم ارتفاع طرح (25 درصد) بالاتر بیاید. برای پیاده سازی این انیمیشن باید کد زیر را به مثال قبل اضافه کنیم :

<Transition ...> 
      <KeyFrameSet> 
           <KeyPosition 
               motion:keyPositionType="parentRelative" 
               motion:percentY="0.25" motion:framePosition="50"
               motion:target="@+id/button"/> 
      </KeyFrameSet> 
</Transition>

مطابق توضیحاتی که دادیم کد "motion:target="@+id/button مشخص می‌کند که ما قصد داریم این کی فریم را روی المان button اعمال کنیم. "motion:framePosition="50 نیز مشخص می‌کند که ما قصد داریم این کی فریم در وسط جابجایی اعمال شود. "motion:percentY="0.25 مشخص کننده‌ی این موضوع است که در زمان اعمال کی فریم button باید به اندازه یک چهارم والدش (25 درصد طرح اصلی ) قرار بگیرد. "motion:keyPositionType="parentRelative نیز مشخص می‌کند کی فریم تعریف شده باید از نوع parentRelative باشد. (در ادامه مقاله به معرفی انواع آن خواهیم پرداخت.)

با اعمال این بخش به کدهای قسمت اول، در نهایت کدها به شکل زیر تغییر می‌کند.

لایوت activity_main.xml: کدهای لایوت activity_main.xml بدون تغییر باقی می‌ماند.

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.motion.MotionLayout
 xmlns:android="https://schemas.android.com/apk/res/android"
 xmlns:tools="https://schemas.android.com/tools"
 xmlns:app="https://schemas.android.com/apk/res-auto"
 android:id="@+id/motionLayout"
 app:layoutDescription="@xml/scene_06"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
    <View 
        android:id="@+id/button"
        android:background="@color/colorAccent"
        android:layout_width="64dp"
        android:layout_height="64dp" /> 
</android.support.constraint.motion.MotionLayout>

کدهای scene_01 :

<?xml version="1.0" encoding="utf-8"?>
<MotionScene
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:motion="https://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000"
        motion:interpolator="linear">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />

        <KeyFrameSet>
            <KeyPosition
                motion:keyPositionType="parentRelative"
                motion:percentY="0.25"
                motion:framePosition="50"
                motion:target="@+id/button"/>
        </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="#D81B60"/>
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="#9999FF"/>
        </Constraint>
    </ConstraintSet>

</MotionScene>

انواع کی فریم موقعیت:

در مثال قبل دیدم که هنگام استفاده از کی فریم موقعیت می‌توانیم مختصات المان را با استفاده از percentY و percentX تعریف کنیم و در حقیقت با تعریف همین percentY و percentX است که حرکت المان به صورت منحنی در می‌آید. یکی از صفاتی که در کی فریم موقعیت باید مشخص شود keyPositionType است که مشخص می‌کند مرجع درصدهایی که برای x و y مشخص می‌کنیم بر اساس چه مختصاتی باشد. در ادامه‌ی مقاله‌ی ساخت انیمیشن در اندروید به بررسی انواع این مراجع مختصات می‌پردازیم.

parentRelative:

زمانی که مقدار parentRelative را برای keyPositionType مشخص کنید مختصات لایوت والد به عنوان مختصات مرجع تعریف می‌شود. همان‌طور که در شکل 2 مشاهده می‌کنید. نسبت مختصات بر اساس اندازه و مختصات طرح کلی (parent) تعریف می‌شود.

این نوع مختصات دهی رایج‌ترین نوع از بین سایرین هست و روشی بسیار ساده و شهودی برای بیان جایگاه کی فریم است. معمولاً از این روش برای جابجایی‌های بزرگی که در کل طرح حرکت می‌کنند، استفاده می‌شود.

deltaRelative:

دومین نوع سیستم مختصات دهی به کی فریم deltaRelative است، که مختصات دهی بر اساس نقاط شروع و پایان انجام می‌شود. در واقع مختصاتی که تعریف می‌کنید، درصدی از فاصله‌ی بین موقعیت‌های شروع و پایان است. در این حالت نقطه‌ی شروع مبدا مختصات و نقطه‌ی پایان حد نهایی محورهای x وy  هستند.

ساخت انیمیشن در اندروید

از این نوع مختصات زمانی استفاده می‌شود که شما قصد دارید نسبت به فاصله بین دو نقطه شروع و پایان تغییری را تعریف کنید. نکته‌ی مهمی در استفاده از این نوع مختصات دهی وجود دارد، همان‌طور که گفتیم دیگر مختصات تعریف شده به مختصات طرح والد وابستگی ندارد و درصدها بر اساس دو نقطه‌ی شروع و پایان محاسبه می‌شوند، اگر در یکی از محورها تفاوت بین این دو نقطه بسیار کم (یا صفر) باشد، موقعیت کلید فریم در محور تغییر نمی‌کند. به عنوان مثال، در مثالی که قبلا بررسی کردیم چون المان از سمت چپ به راست بر روی صفحه نمایش حرکت می‌کند و ارتفاع بین دو نقطه یکسان هست، اگر از deltaRelative استفاده کنیم و position=0.25 را تعریف کنیم، ارتفاع المان هیچ تغییری نخواهد داشت.

pathRelative:

pathRelative هم مانند deltaRelative بر اساس نقاط شروع و پایان مختصات را مشخص می‌کند. در حالت قبل نقطه‌ی شروع مبدا مختصات و نقطه‌ی پایان حد نهایی محورهای x وy  بودند ولی در  pathRelative مطابق با شکل پایین، مسیر مستقیمی بین دو نقطه‌ی شروع و پایان محور افقی مختصات را تشکیل می‌دهد. در نوع مختصات دهی از اعداد منفی نیز پشتیبانی می‌کند و می‌توانید از اعداد منفی نیز استفاده کنید.

ساخت انیمیشن در اندروید

کی فریم صفات (Attribute keyframe):

کی فریم صفات شبیه به کی فریم‌های موقعیت هستند، اما به جای موقعیت المان روی صفات المان کار می‌کنند. کی فریم صفات این امکان را به شما می‌دهد که در طول جابجایی از نقطه‌ی شروع به نقطه‌ی پایان انیمیشن ، در یک نقطه‌ی معین . ویژگی‌های خاصی از یک المان را مانند رنگ،اندازه،مقیاس و... تغییر بدهید.

در مثال قبل المان تعریف شده، زمانی که به وسط جابجایی می‌رسید ارتفاع آن به میزان یک چهارم ارتفاع والدش بالاتر می‌رفت، حال می‌خواهیم در همان نقطه علاوه بر تغییر ارتفاع، مقیاس المان بزرگ‌تر شود و به اندازه‌ی 45 درجه نیز بچرخد.برای انجام این کار علاوه بر کی فریم موقعیت، از Attribute keyframe نیز استفاده می‌کنیم و KeyFrameSet را به صورت زیر تغییر می‌دهیم:

<KeyFrameSet>
    <KeyAttribute
        android:rotation="-45"
        android:scaleX="2"
        android:scaleY="2"
        motion:framePosition="50"
        motion:target="@id/button" />
    <KeyPosition
        motion:framePosition="50"
        motion:keyPositionType="screenRelative"
        motion:percentY="0.2"
        motion:target="@id/button" />
</KeyFrameSet>

در نهایت فایل MotionScene به صورت زیر تغییر خواهد کرد و خروجی کار مشابه با ویدیو شماره 2 خواهد شد.

<?xml version="1.0" encoding="utf-8"?>
<MotionScene
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:motion="https://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000"
        motion:interpolator="linear">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />

        <KeyFrameSet>
            <KeyAttribute
                android:scaleX="2"
                android:scaleY="2"
                android:rotation="-45"
                motion:framePosition="50"
                motion:target="@id/button" />
            <KeyPosition
                motion:keyPositionType="screenRelative"
                motion:percentY="0.2"
                motion:framePosition="50"
                motion:target="@id/button"/>
        </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="#D81B60"/>
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="#9999FF"/>
        </Constraint>
    </ConstraintSet>

</MotionScene>

صفات قابل تغییر:

در هنگام استفاده از کی فریم صفات، شما مجازید هر یک از صفات زیر را به صورت دلخواه تغییر بدهید:

  • visibility
  • alpha
  • elevation
  •  rotation و rotationX و rotationY
  • scaleX و scaleY
  • translationX و translationY و translationZ

نکته: مشابه آنچه در ConstraintSet داشتیم ، در کی فریم‌ها نیز شما می‌توانید با افزودن <CustomAttribute> ویژگی‌های سفارشی را برای کی فریم‌ خود تعریف کنید و صفاتی را علاوه بر موارد بالا در المان مورد نظرتان تغییر بدهید.

جمع بندی

در این مقاله سعی کردیم شما را با کلیات چگونگی ساخت انیمیشن در اندروید با  استفاده از موشن‌ لایوت آشنا کنیم. و به مهم‌ترین موضوعات و نکات استفاده از موشن لایوت پرداختیم و در مورد کاربردها و چگونگی ایجاد MotionScene و اجزای آن صحبت کردیم. همچنین یک نمونه بسیار ساده استفاده از آن را انجام دادیم. شما می‌توانید با ترکیب موضوعات بیان شده و استفاده ترکیبی موشن لایوت و viewPager ,CoordinatorLayout , DrawerLayout طرح‌های بسیار جذابی را پیاده سازی کنید.

نمونه طرح‌های پیاده شده زیادی با عنوان MotionLayout / Constraint Layout Samples در سایت Github وجود دارد که می‌توانید  به‌عنوان مرجع از آنها استفاده کنید.

اگر به یادگیری بیشتر در زمینه‌ی اندروید علاقه داری، با شرکت در دوره‌ی آموزشی متخصص اندروید در کمتر از یکسال به یک توسعه‌دهنده اندروید همه فن حریف تبدیل می‌شوی که آماده‌ی استخدام، دریافت پروژه و حتی پیاده‌سازی اپلیکیشن خودت هستی.

منبع : https://developer.android.com

 

چه امتیازی به این مقاله می دید؟

نظرات کاربران

سپهر تابعیان

سپاس

امیر حسین حیدری

خواهش می‌کنم

Behrouz Alborzi

مطلب عالی بود واقعا … ای کاش بشه یه قسمت های اپ های ایرانی از اینها استفاده میکنن هم اشاره داشت مث اسنپ قسمت navigationMenu

امیر حسین حیدری

از این که دوست داشین خوشحالیم انشالله در ادامه بهش اشاره میکنیم

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :