برای ژست برگشتی پیش بینی کننده پشتیبانی اضافه کنید

شکل ۱. ماکت ظاهر و حس ژست پیش‌بینی‌کننده‌ی بازگشت در یک تلفن

قابلیت بازگشت پیش‌بینی‌کننده، یک قابلیت ناوبری حرکتی، به کاربران اجازه می‌دهد تا پیش‌نمایشی از جایی که کشیدن انگشت به عقب آنها را می‌برد، مشاهده کنند.

برای مثال، استفاده از یک حرکت برگشت می‌تواند پیش‌نمایشی متحرک از صفحه اصلی را در پشت برنامه شما نمایش دهد، همانطور که در ماکت شکل ۱ نشان داده شده است.

از اندروید ۱۵ به بعد، گزینه توسعه‌دهنده برای انیمیشن‌های پیش‌بینی‌کننده بازگشت دیگر در دسترس نیست. انیمیشن‌های سیستمی مانند بازگشت به خانه، بین وظایف و بین فعالیت‌ها اکنون برای برنامه‌هایی که به طور کامل یا در سطح فعالیت، ژست پیش‌بینی‌کننده بازگشت را انتخاب کرده‌اند، ظاهر می‌شوند.

شما می‌توانید این انیمیشن بازگشت به خانه را آزمایش کنید (همانطور که در بخش بعدی این صفحه توضیح داده شده است).

پشتیبانی از ژست بازگشت پیش‌بینی‌کننده نیازمند به‌روزرسانی برنامه، استفاده از API سازگار با نسخه‌های قبلی OnBackPressedCallback AppCompat 1.6.0-alpha05 (AndroidX) یا بالاتر، یا استفاده از API پلتفرم جدید OnBackInvokedCallback است. اکثر برنامه‌ها از API سازگار با نسخه‌های قبلی AndroidX استفاده می‌کنند.

این به‌روزرسانی یک مسیر مهاجرت برای رهگیری صحیح ناوبری برگشتی ارائه می‌دهد که شامل جایگزینی رهگیری‌های برگشتی از KeyEvent.KEYCODE_BACK و هر کلاسی با متدهای onBackPressed مانند Activity و Dialog با APIهای جدید سیستم Back است.

ویدیوی Codelab و Google I/O

علاوه بر استفاده از این مستندات در این صفحه، codelab ما را نیز امتحان کنید . این codelab یک پیاده‌سازی رایج از WebView را ارائه می‌دهد که با استفاده از APIهای AndroidX Activity، حرکت پیش‌بینی‌کننده‌ی بازگشت را مدیریت می‌کند.

همچنین می‌توانید ویدیوی Google I/O ما را مشاهده کنید که مثال‌های بیشتری از پیاده‌سازی AndroidX و APIهای پلتفرم را پوشش می‌دهد.

به‌روزرسانی برنامه‌ای که از ناوبری پیش‌فرض به عقب استفاده می‌کند

قابلیت پیش‌بینی بازگشت به عقب به طور پیش‌فرض فعال است.

اگر برنامه شما از Fragments یا کامپوننت Navigation استفاده می‌کند، آن را به AndroidX Activity 1.6.0-alpha05 یا بالاتر نیز ارتقا دهید.

برنامه‌ای را که از پیمایش سفارشی به عقب استفاده می‌کند، به‌روزرسانی کنید

اگر برنامه شما رفتار بازگشت سفارشی را پیاده‌سازی می‌کند، بسته به اینکه آیا از AndroidX استفاده می‌کند یا خیر و نحوه مدیریت ناوبری بازگشت، مسیرهای مهاجرت متفاوتی وجود دارد.

برنامه شما از AndroidX استفاده می‌کند نحوه مدیریت ناوبری برگشتی در اپلیکیشن شما مسیر مهاجرت پیشنهادی (لینک در همین صفحه)
بله رابط‌های برنامه‌نویسی کاربردی اندروید ایکس انتقال یک پیاده‌سازی موجود AndroidX به نسخه قبلی
APIهای پلتفرم پشتیبانی نشده یک برنامه AndroidX حاوی APIهای ناوبری برگشتی پشتیبانی نشده را به APIهای AndroidX منتقل کنید
خیر API های پلتفرم پشتیبانی نشده، قابل انتقال برنامه‌ای را که از APIهای ناوبری پشتیبانی نشده استفاده می‌کند، به APIهای پلتفرم منتقل کنید
API های پلتفرم پشتیبانی نشده، اما قادر به مهاجرت نیستند با تنظیم ویژگی android:enableOnBackInvokedCallback به false در تگ <application> یا <activity> از فایل AndroidManifest.xml برنامه خود، موقتاً از این قابلیت انصراف دهید.

انتقال یک پیاده‌سازی ناوبری برگشتی AndroidX

این مورد استفاده رایج‌ترین (و توصیه‌شده‌ترین) است. این مورد در مورد برنامه‌های جدید یا موجود که مدیریت ناوبری ژست‌های سفارشی را با OnBackPressedDispatcher پیاده‌سازی می‌کنند، همانطور که در بخش «ارائه ناوبری برگشت سفارشی» توضیح داده شده است، اعمال می‌شود.

برای اطمینان از اینکه APIهایی که از قبل از OnBackPressedDispatcher استفاده می‌کنند (مانند Fragments و کامپوننت Navigation) به طور یکپارچه با حرکت پیش‌بینی‌کننده‌ی بازگشت کار می‌کنند، به AndroidX Activity 1.6.0-alpha05 ارتقا دهید.

```xml
// In your build.gradle file:
dependencies {

// Add this in addition to your other dependencies
implementation "androidx.activity:activity:1.6.0-alpha05"
```

یک برنامه AndroidX حاوی APIهای ناوبری برگشتی پشتیبانی نشده را به APIهای AndroidX منتقل کنید

اگر برنامه شما از کتابخانه‌های AndroidX استفاده می‌کند اما APIهای ناوبری برگشتی پشتیبانی نشده را پیاده‌سازی یا به آنها ارجاع می‌دهد، برای پشتیبانی از رفتار جدید باید به استفاده از APIهای AndroidX مهاجرت کنید.

برای انتقال APIهای پشتیبانی نشده به APIهای AndroidX:

  1. منطق مدیریت بازگشت سیستم خود را با پیاده‌سازی OnBackPressedCallback به OnBackPressedDispatcher اندروید ایکس منتقل کنید. برای راهنمایی دقیق، به بخش «ارائه ناوبری بازگشت سفارشی» مراجعه کنید.

  2. وقتی آماده‌اید تا جلوی رهگیری حرکت برگشت را بگیرید، OnBackPressedCallback را غیرفعال کنید.

  3. متوقف کردن رهگیری رویدادهای برگشتی از طریق OnBackPressed یا KeyEvent.KEYCODE_BACK .

  4. حتماً به AndroidX Activity 1.6.0-alpha05 ارتقا دهید.

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    

برنامه‌ای را که از APIهای ناوبری پشتیبانی نشده استفاده می‌کند، به APIهای پلتفرم منتقل کنید

اگر برنامه شما نمی‌تواند از کتابخانه‌های AndroidX استفاده کند و در عوض با استفاده از APIهای پشتیبانی نشده، ناوبری Back سفارشی را پیاده‌سازی یا به آن ارجاع می‌دهد، باید به API پلتفرم OnBackInvokedCallback مهاجرت کنید.

برای انتقال APIهای پشتیبانی نشده به API پلتفرم، مراحل زیر را انجام دهید:

  1. در دستگاه‌هایی که اندروید ۱۳ یا بالاتر دارند از API جدید OnBackInvokedCallback استفاده کنید و در دستگاه‌هایی که اندروید ۱۲ یا پایین‌تر دارند، به APIهای پشتیبانی‌نشده تکیه کنید.

  2. منطق برگشت سفارشی خود را در OnBackInvokedCallback با onBackInvokedDispatcher ثبت کنید. این کار از اتمام فعالیت فعلی جلوگیری می‌کند و callback شما فرصتی برای واکنش به عمل برگشت پس از تکمیل پیمایش برگشت سیستم توسط کاربر، پیدا می‌کند.

  3. وقتی آماده‌اید تا جلوی رهگیری حرکت برگشت را بگیرید، OnBackInvokedCallback لغو ثبت کنید. در غیر این صورت، کاربران ممکن است هنگام استفاده از پیمایش برگشت سیستم، رفتار نامطلوبی را مشاهده کنند - برای مثال، "گیر کردن" بین نماها و مجبور شدن به ترک اجباری برنامه شما.

    در اینجا مثالی از نحوه‌ی انتقال منطق از onBackPressed آورده شده است:

    کاتلین

    @Override
    fun onCreate() {
        if (BuildCompat.isAtLeastT()) {
            onBackInvokedDispatcher.registerOnBackInvokedCallback(
                OnBackInvokedDispatcher.PRIORITY_DEFAULT
            ) {
                /**
                 * onBackPressed logic goes here. For instance:
                 * Prevents closing the app to go home screen when in the
                 * middle of entering data to a form
                 * or from accidentally leaving a fragment with a WebView in it
                 *
                 * Unregistering the callback to stop intercepting the back gesture:
                 * When the user transitions to the topmost screen (activity, fragment)
                 * in the BackStack, unregister the callback by using
                 * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
                 * (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
                 */
            }
        }
    }

    جاوا

    @Override
    void onCreate() {
      if (BuildCompat.isAtLeastT()) {
        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
            () -> {
              /**
               * onBackPressed logic goes here - For instance:
               * Prevents closing the app to go home screen when in the
               * middle of entering data to a form
               * or from accidentally leaving a fragment with a WebView in it
               *
               * Unregistering the callback to stop intercepting the back gesture:
               * When the user transitions to the topmost screen (activity, fragment)
               * in the BackStack, unregister the callback by using
               * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
               * (https://developer.android.com/reference/kotlin/android/view/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
               */
            }
        );
      }
    }
  4. متوقف کردن رهگیری رویدادهای برگشتی با استفاده از OnBackPressed یا KeyEvent.KEYCODE_BACK برای اندروید ۱۳ و بالاتر.

شما می‌توانید یک OnBackInvokedCallback با PRIORITY_DEFAULT یا PRIORITY_OVERLAY ثبت کنید، که در AndroidX OnBackPressedCallback مشابه موجود نیست. ثبت یک callback با PRIORITY_OVERLAY در برخی موارد مفید است.

این مورد زمانی اعمال می‌شود که شما از onKeyPreIme() مهاجرت می‌کنید و callback شما نیاز دارد که به جای یک IME باز، ژست برگشتی را دریافت کند. IMEها هنگام باز شدن، callbackها را با PRIORITY_DEFAULT ثبت می‌کنند. callback خود را با PRIORITY_OVERLAY ثبت کنید تا مطمئن شوید OnBackInvokedDispatcher ژست برگشتی را به callback شما به جای IME باز ارسال می‌کند.

از حالت پیش‌بینی‌شده‌ی بازگشت انصراف دهید

برای انصراف، در AndroidManifest.xml ، در تگ <application> ، پرچم android:enableOnBackInvokedCallback روی false تنظیم کنید.

<application
    ...
    android:enableOnBackInvokedCallback="false"
    ... >
...
</application>

تنظیم این مقدار روی false موارد زیر را انجام می‌دهد:

  • انیمیشن سیستم پیش‌بینی حرکت برگشت را غیرفعال می‌کند.
  • OnBackInvokedCallback نادیده می‌گیرد، اما فراخوانی‌های OnBackPressedCallback به کار خود ادامه می‌دهند.

انصراف در سطح فعالیت

پرچم android:enableOnBackInvokedCallback به شما امکان می‌دهد انیمیشن‌های سیستم پیش‌بینی‌کننده را در سطح فعالیت غیرفعال کنید. این رفتار، انتقال برنامه‌های بزرگ چندفعالیتی به حرکات پیش‌بینی‌کننده بازگشت را قابل مدیریت‌تر می‌کند.

کد زیر مثالی از enableOnBackInvokedCallback تنظیم شده برای فعال کردن انیمیشن سیستم بازگشت به خانه از MainActivity را نشان می‌دهد:

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

هنگام استفاده از پرچم android:enableOnBackInvokedCallback

  • تنظیم android:enableOnBackInvokedCallback=false انیمیشن‌های پیش‌بینی‌کننده‌ی بازگشت را چه در سطح فعالیت و چه در سطح برنامه، بسته به جایی که تگ را تنظیم می‌کنید، غیرفعال می‌کند و به سیستم دستور می‌دهد که فراخوانی‌ها به API پلتفرم OnBackInvokedCallback را نادیده بگیرد. با این حال، فراخوانی‌های OnBackPressedCallback همچنان اجرا می‌شوند زیرا OnBackPressedCallback با نسخه‌های قبلی سازگار است و API onBackPressed را فراخوانی می‌کند، که قبل از اندروید ۱۳ پشتیبانی نمی‌شود.
  • تنظیم پرچم enableOnBackInvokedCallback در سطح برنامه، مقدار پیش‌فرض را برای همه فعالیت‌های برنامه تعیین می‌کند. می‌توانید با تنظیم این پرچم در سطح فعالیت، همانطور که در مثال کد قبلی نشان داده شده است، مقدار پیش‌فرض را برای هر فعالیت لغو کنید.

بهترین شیوه‌های پاسخگویی به تماس

در اینجا بهترین شیوه‌ها برای استفاده از فراخوانی‌های برگشتی پشتیبانی‌شده توسط سیستم آمده است؛ BackHandler (برای Compose)، OnBackPressedCallback یا OnBackInvokedCallback .

وضعیت رابط کاربری که هر فراخوانی برگشتی را فعال و غیرفعال می‌کند، تعیین کنید.

وضعیت رابط کاربری (UI state) یک ویژگی (property) است که رابط کاربری (UI) را توصیف می‌کند. توصیه می‌کنیم این مراحل سطح بالا را دنبال کنید.

  1. وضعیت رابط کاربری که هر فراخوانی برگشتی را فعال و غیرفعال می‌کند، تعیین کنید.

  2. آن وضعیت را با استفاده از یک نوع نگهدارنده داده قابل مشاهده ، مانند StateFlow یا Compose State، تعریف کنید و با تغییر وضعیت، فراخوانی مجدد را فعال یا غیرفعال کنید.

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

استفاده از فراخوانی‌های سیستمی برای منطق رابط کاربری

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

اگر برنامه شما OnBackPressedCallback یا OnBackInvokedCallback با PRIORITY_DEFAULT یا PRIORITY_OVERLAY فعال کند، انیمیشن‌های پیش‌بین back اجرا نمی‌شوند و شما باید رویداد back را مدیریت کنید. این callbackها را برای اجرای منطق کاری یا ثبت وقایع ایجاد نکنید.

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

  • در دستگاه‌هایی که اندروید ۱۶ و بالاتر دارند، از OnBackInvokedCallback به همراه PRIORITY_SYSTEM_NAVIGATION_OBSERVER استفاده کنید. این کار یک تابع فراخوانی ناظر (Observer-callback) ایجاد می‌کند که رویداد بازگشت (back event) را مصرف نمی‌کند. برای مثال، می‌توانید این تابع فراخوانی را زمانی ثبت کنید که کاربر از اکتیویتی ریشه به عقب برمی‌گردد، یا به عبارت دیگر، زمانی که کاربر برنامه شما را ترک کرده است. در این حالت، می‌توانید رویداد بازگشت را ثبت کنید یا منطق کاری دیگری را اجرا کنید، و انیمیشن بازگشت به خانه همچنان پخش خواهد شد.
  • برای موارد فعالیت به فعالیت یا موارد قطعه به فعالیت، اگر isFinishing درون onDestroy درون چرخه حیات Activity true باشد، لاگ کنید.
  • برای موارد قطعه به قطعه، اگر isRemoving درون onDestroy درون چرخه حیات نمای قطعه درست باشد، لاگ کنید. یا با استفاده از متدهای onBackStackChangeStarted یا onBackStackChangeCommitted درون FragmentManager.OnBackStackChangedListener لاگ بگیرید.
  • برای مورد Compose، در تابع فراخوانی onCleared() از ViewModel مرتبط با مقصد Compose، لاگ بگیرید. این بهترین سیگنال برای اطلاع از زمانی است که یک مقصد compose از پشته حذف و نابود می‌شود.

ایجاد فراخوانی‌های تک مسئولیتی

شما می‌توانید چندین فراخوانی برگشتی به dispatcher اضافه کنید. فراخوانی‌های برگشتی به یک پشته اضافه می‌شوند که در آن آخرین فراخوانی برگشتی فعال‌شده، ژست برگشتی بعدی را با یک فراخوانی برگشتی برای هر ژست برگشتی مدیریت می‌کند.

اگر یک فراخوانی برگشتی تنها یک مسئولیت داشته باشد، مدیریت وضعیت فعال آن آسان‌تر است. برای مثال:

ترتیب فراخوانی‌های برگشتی در یک پشته.
شکل ۲. نمودار پشته فراخوانی.

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

فراخوانی دیگر می‌تواند شامل یک کامپوننت متریال باشد که از پیش‌بینی پشتیبانی می‌کند، یک انتقال AndroidX با استفاده از APIهای Progress یا یک فراخوانی سفارشی دیگر.

یک تابع فراخوانی childFragmentManager در صورتی اجرا می‌شود که توابع فراخوانی فوق غیرفعال باشند و پشته پشتی این FragmentManager خالی نباشد، جایی که childFragmentManager درون یک Fragment متصل شده است. در این مثال، این تابع فراخوانی داخلی غیرفعال است.

به همین ترتیب، فراخوانی داخلی supportFragmentManager در صورتی اجرا می‌شود که فراخوانی‌های فوق غیرفعال باشند و پشته آن خالی نباشد. این رفتار هنگام استفاده از FragmentManager یا NavigationComponent برای ناوبری ثابت است، زیرا NavigationComponent به FragmentManager متکی است. در این مثال، این فراخوانی در صورتی اجرا می‌شود که کاربر متنی را در فرم وارد نکرده باشد و باعث غیرفعال شدن فراخوانی "Are you sure..." شود.

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

انیمیشن پیش‌بینی حرکت برگشت را آزمایش کنید

اگر هنوز از اندروید ۱۳ یا اندروید ۱۴ استفاده می‌کنید، می‌توانید انیمیشن بازگشت به خانه نشان داده شده در شکل ۱ را آزمایش کنید.

برای آزمایش این انیمیشن، مراحل زیر را انجام دهید:

  1. در دستگاه خود، به تنظیمات > سیستم > گزینه‌های توسعه‌دهنده بروید.

  2. انیمیشن‌های پیش‌بینی‌کننده‌ی بازگشت را انتخاب کنید.

  3. برنامه‌ی به‌روزرسانی‌شده‌تان را اجرا کنید و با استفاده از ژست حرکتی «بازگشت» (back) آن را در عمل مشاهده کنید.