התחלת פעילות באמצעות אנימציה

מעברי פעילויות באפליקציות של Material Design מספקים חיבורים חזותיים בין מצבים שונים באמצעות תנועה וטרנספורמציות בין יסודות משותפים. ניתן להגדיר אנימציות מותאמות אישית למעברי כניסה ויציאה, מעברים של אלמנטים משותפים בין פעילויות.

איור 1. א' עם רכיבים משותפים.

  • מעבר כניסה קובע את האופן שבו צפיות בפעילות להיכנס לסצנה. לדוגמה, במעבר של explode, הערך של נכנסים לסצנה מבחוץ ועולים פנימה למרכז מסך.
  • מעבר ליציאה קובע איך צפיות ביציאה מפעילות את הסצנה. לדוגמה, במעבר ליציאה של explode, התצוגות לצאת מהסצנה מחוץ למרכז.
  • מעבר של רכיבים משותפים קובע איך תצוגות שמשותפות בין שתי פעילויות מעבר בין הפעילויות האלה. לדוגמה, אם לשתי פעילויות יש את אותה תמונה במיקומים ובגדלים שונים, מעבר של רכיב משותף אחד (changeImageTransform) מתורגם ו משנה את גודל התמונה בצורה חלקה בין הפעילויות האלה.

מערכת Android תומכת במעברי כניסה ויציאה הבאים:

  • explode: הזזת תצוגות לכיוון מרכז הסצנה או החוצה ממנה.
  • slide: הזזה של תצוגות פנימה או החוצה מאחד מהקצוות של לסצנה.
  • fade: הוספה או הסרה של תצוגה מהסצנה על ידי שינוי שלה אטימוּת.

כל מעבר שמאריך את המחלקה Visibility נתמך כמעבר לכניסה או ליציאה. לקבלת מידע נוסף, עיינו במשאבי העזרה של ה-API Transition בכיתה.

מערכת Android תומכת גם במעברים הבאים של רכיבים משותפים:

  • changeBounds: אנימציית השינויים בגבולות הפריסה של היעד צפיות.
  • changeClipBounds: אנימציית השינויים בגבולות הקליפ של היעד צפיות.
  • changeTransform: מייצרת אנימציה של השינויים בקנה המידה ובסיבוב של צפיות ביעד.
  • changeImageTransform: ממחיש את השינויים בגודל ובקנה המידה של לתמונות היעד.

כשמפעילים מעברים בין פעילויות באפליקציה, מופעל בין פעילויות הכניסה והיציאה.

איור 2. מעבר בין סצנות עם רכיב משותף אחד.

לקבלת קוד לדוגמה שיוצר אנימציה בין פעילויות באמצעות אלמנטים משותפים: ActivitySceneTransitionBasic.

בדיקה של גרסת המערכת

ממשקי ה-API למעבר בין פעילויות זמינים ב-Android מגרסה 5.0 (API 21) ואילך. כדי לשמור על תאימות לגרסאות קודמות של Android, צריך לבדוק את מערכת version בזמן הריצה לפני להפעיל את ממשקי ה-API בשביל כל אחת מהתכונות הבאות:

Kotlin

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

Java

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

ציון מעברים מותאמים אישית

קודם כול, מפעילים מעברי תוכן בחלון באמצעות android:windowActivityTransitions כשמגדירים סגנון שירש מהעיצוב 'חומר'. אפשר גם לציין הזנת, יציאה ומעברים בין רכיבים משותפים בהגדרת הסגנון שלכם:

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:windowActivityTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

המעבר של change_image_transform בדוגמה הזו מוגדר כך:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

הרכיב changeImageTransform תואם כיתה אחת (ChangeImageTransform). מידע נוסף זמין בממשק ה-API עבור Transition.

כדי להפעיל מעברי תוכן בחלון במקום זאת, צריך לקרוא אל פונקציית Window.requestFeature():

Kotlin

// Inside your activity (if you did not enable transitions in your theme)
with(window) {
    requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)

    // Set an exit transition
    exitTransition = Explode()
}

Java

// Inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);

// Set an exit transition
getWindow().setExitTransition(new Explode());

כדי לציין מעברים בקוד, צריך לקרוא לפונקציות האלה באמצעות אובייקט Transition:

setExitTransition() וגם פונקציות setSharedElementExitTransition() מגדירות את היציאה מעבר לפעילות הקריאה. setEnterTransition() וגם פונקציות setSharedElementEnterTransition() מגדירות את הכניסה את המעבר לפעילות שנקראה.

כדי לקבל את ההשפעה המלאה של המעבר, צריך להפעיל את התוכן בחלון עובר גם בפעילות הקריאה וגם בפעילויות הנקראות. אחרת, הפונקציה הפעילות תתחיל את מעבר היציאה, אבל לאחר מכן יופיע החלון מעברים שונים, כמו שינוי מרחק או עמעום.

כדי להתחיל את המעבר בהקדם האפשרי, צריך להשתמש Window.setAllowEnterTransitionOverlap() בפעילות שנקראת. כך תוכלו לבצע מעברים דרמטיים יותר לכניסה.

התחלת פעילות באמצעות מעברים

אם מפעילים מעברים ומגדירים מעבר יציאה עבור פעילות, המעבר מופעל כשמפעילים פעילות אחרת, באופן הבא:

Kotlin

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle())

Java

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

אם תגדירו מעבר כניסה עבור הפעילות השנייה, גם המעבר הזה מופעלת כשהפעילות מתחילה. כדי להשבית מעברים כשמתחילים פעילות אחרת, צריך לספק חבילת אפשרויות של null.

התחלת פעילות עם רכיב משותף

כדי ליצור אנימציית מעבר בין המסך בין שתי פעילויות שכוללות רכיב משותף, יש לבצע את הפעולות הבאות:

  1. הפעלת מעברי תוכן בחלון בעיצוב שלך.
  2. מציינים מעבר של רכיבים משותפים בסגנון שלכם.
  3. מגדירים את המעבר כמשאב XML.
  4. מקצים שם משותף לרכיבים המשותפים בשתי הפריסות עם מאפיין android:transitionName.
  5. צריך להשתמש בפונקציה ActivityOptions.makeSceneTransitionAnimation().

Kotlin

// Get the element that receives the click event
val imgContainerView = findViewById<View>(R.id.img_container)

// Get the common element for the transition in this activity
val androidRobotView = findViewById<View>(R.id.image_small)

// Define a click listener
imgContainerView.setOnClickListener( {
    val intent = Intent(this, Activity2::class.java)
    // Create the transition animation - the images in the layouts
    // of both activities are defined with android:transitionName="robot"
    val options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot")
    // Start the new activity
    startActivity(intent, options.toBundle())
})

Java

// Get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// Get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// Define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // Create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // Start the new activity
        startActivity(intent, options.toBundle());
    }
});

בתצוגות דינמיות משותפות שאתם יוצרים בקוד שלכם, השתמשו הפונקציה View.setTransitionName() כדי לציין שם רכיב משותף פעילויות.

כדי להפוך את אנימציית המעבר בין הסצנות בסיום הפעילות השנייה, צריך להפעיל את Activity.finishAfterTransition() במקום Activity.finish().

התחלת פעילות עם מספר אלמנטים משותפים

כדי ליצור אנימציית מעבר בין סצנות בין שתי פעילויות שכוללות מרכיב משותף אחד, להגדיר את הרכיבים המשותפים בשתי הפריסות עם android:transitionName — או להשתמש הפונקציה View.setTransitionName() פועלת בשתי הפעילויות – וגם ליצור ActivityOptions כאובייקט:

Kotlin

// Rename the Pair class from the Android framework to avoid a name clash
import android.util.Pair as UtilPair
...
val options = ActivityOptions.makeSceneTransitionAnimation(this,
        UtilPair.create(view1, "agreedName1"),
        UtilPair.create(view2, "agreedName2"))

Java

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"),
        Pair.create(view2, "agreedName2"));