אתם יכולים ליצור אנימציות ומעברים מותאמים אישית של נכסים בתוך האפליקציה, אנימציות מותאמות אישית בין פעילויות ואנימציות מותאמות אישית בין קטעים עם תנועות ניווט חזויות אחורה באמצעות Views או Compose. כדי לנסות את השיטה של Compose, אפשר לעיין במאמר בנושא הוספת תמיכה באנימציות חזויות של חזרה.
הוספה של מעברים בהתאמה אישית באמצעות Progress API
אם משתמשים ב-AndroidX Activity בגרסה 1.8.0-alpha01 ומעלה, אפשר להשתמש בממשקי ה-API של התקדמות התנועה חזרה כדי לפתח אנימציות מותאמות אישית לתנועת החזרה החזויה באפליקציה. ממשקי ה-API של התקדמות התנועה חזרה שימושיים להנפשת תצוגות, אבל יש להם מגבלות כשמנפישים מעברים בין קטעים. ב-OnBackPressedCallback הוספנו את השיטות handleOnBackProgressed, handleOnBackCancelled ו-handleOnBackStarted כדי להנפיש אובייקטים בזמן שהמשתמש מחליק אחורה. אפשר להשתמש בשיטות האלה אם רוצים להתאים אישית יותר מאשר את האנימציות שמוגדרות כברירת מחדל במערכת, או את האנימציות של רכיבי Material.
אנחנו מצפים שרוב האפליקציות ישתמשו בממשקי AndroidX API שתואמים לגרסאות קודמות, אבל יש גם ממשקי API דומים לפלטפורמה בממשק OnBackAnimationCallback שזמינים לבדיקה ב-Android 14 ובגרסאות מתקדמות יותר.
שימוש בממשקי Progress API עם AndroidX Transitions
אפשר להשתמש בממשקי Progress API עם AndroidX Transitions בגרסה 1.5.0-alpha01 ואילך ב-Android 14 ואילך כדי ליצור מעברים של חזרה עם חיזוי.
- כדי להפעיל מעברים כשהמשתמש מחליק אחורה, צריך להשתמש ב-
TransitionManager#controlDelayedTransitionבמקום ב-beginDelayedTransition. - יוצרים את המעבר בתוך
handleOnBackStarted. - מפעילים את המעבר עם אירוע החזרה בתוך
handleOnBackProgressedעל ידי קישורcurrentFractionאלBackEvent.progress, וכך אפשר לראות עד כמה המשתמש החליק אחורה. - השלמת המעבר אחרי שהמשתמש מבצע את תנועת החזרה ב-
handleOnBackPressed. - לבסוף, מאפסים את מצב המעבר בתוך
handleOnBackCancelled.
בסרטון הבא, בקוד Kotlin וב-XML מוצגת דוגמה למעבר מותאם אישית בין שני תיבות שהוטמעו באמצעות OnBackPressedCallback:
class MyFragment : Fragment() { val transitionSet = TransitionSet().apply { addTransition(Fade(Fade.MODE_OUT)) addTransition(ChangeBounds()) addTransition(Fade(Fade.MODE_IN)) } ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val callback = object : OnBackPressedCallback(enabled = false) { var controller: TransitionSeekController? = null @RequiresApi(34) override fun handleOnBackStarted(backEvent: BackEvent) { // Create the transition controller = TransitionManager.controlDelayedTransition( binding.card, transitionSet ) changeTextVisibility(ShowText.SHORT) } @RequiresApi(34) override fun handleOnBackProgressed(backEvent: BackEvent) { // Play the transition as the user swipes back if (controller?.isReady == true) { controller?.currentFraction = backEvent.progress } } override fun handleOnBackPressed() { // Finish playing the transition when the user commits back controller?.animateToEnd() this.isEnabled = false } @RequiresApi(34) override fun handleOnBackCancelled() { // If the user cancels the back gesture, reset the state transition(ShowText.LONG) } } binding.shortText.setOnClickListener { transition(ShowText.LONG) callback.isEnabled = true } this.requireActivity().onBackPressedDispatcher.addCallback(callback) } private fun transition(showText: ShowText) { TransitionManager.beginDelayedTransition( binding.card, transitionSet ) changeTextVisibility(showText) } enum class ShowText { SHORT, LONG } private fun changeTextVisibility(showText: ShowText) { when (showText) { ShowText.SHORT -> { binding.shortText.isVisible = true binding.longText.isVisible = false } ShowText.LONG -> { binding.shortText.isVisible = false binding.longText.isVisible = true } } } }
<?xml version="1.0" encoding="utf-8"?>
...
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...>
<TextView
android:id="@+id/short_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
... />
<TextView
android:id="@+id/long_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
.../>
</androidx.constraintlayout.widget.ConstraintLayout>
כשעובדים עם מעברים של תצוגה מקדימה של חזרה, חשוב לזכור את הדברים הבאים:
- משתמשים ב-
isSeekingSupportedכדי לבדוק אם המעבר תומך בתכונה 'חיזוי החזרה'. - מחליפים את
isSeekingSupportedכדי להחזיר true למעברים המותאמים אישית. - יוצרים בקר אחד לכל אנימציה.
- מעברים עם חיזוי של חזרה אחורה נתמכים במעברים של AndroidX, אבל לא במעברים של framework. צריך להפסיק להשתמש במעברים של framework ולעבור לשימוש ב-
Animatorובמעברים של AndroidX. - מעברים עם חיזוי של חזרה נתמכים במכשירים עם Android מגרסה 14 ואילך, והם לא תואמים לאחור.
- יש תמיכה גם במעברים שנוצרו באמצעות סצנות XML. ב-
handleOnBackStarted, מגדירים אתTransitionSeekControllerלתוצאה שלTransitionManager.createSeekControllerבמקום לתוצאה שלcontrolDelayedTransition.