ارائه پیمایش به عقب سفارشی

کاربران بااستفاده از پیمایش به عقب در صفحه‌ها به عقب پیمایش می‌کنند. اکثر دستگاه‌های Android دکمه برگشت (فیزیکی، نرم‌افزاری، یا مبتنی بر اشاره) دارند. معمولاً نباید به برنامه‌تان دکمه برگشت اضافه کنید. بااین‌حال، دستگاه‌های «سیستم عامل Android Automotive» (AAOS) در حالت سازگاری از دکمه برگشت سیستم استفاده می‌کنند. این دکمه پیمایش را مدیریت می‌کند، بنابراین نیازی نیست دکمه خودتان را اضافه کنید. برای جزئیات، حالت سازگاری سیستم‌عامل Android Automotive را ببینید.

‫Android با حرکت کاربر در سراسر برنامه‌تان، پشته برگشتی از مقصدها را حفظ می‌کند. این کار معمولاً به Android اجازه می‌دهد وقتی دکمه «برگشت» فشار داده می‌شود، به‌درستی به مقصدهای قبلی پیمایش کند. بااین‌حال، در چند مورد، برنامه شما ممکن است نیاز داشته باشد رفتار «بازگشت» خود را پیاده‌سازی کند تا بهترین تجربه کاربری ممکن را ارائه دهد. برای مثال، هنگام استفاده از WebView، ممکن است بخواهید رفتار پیش‌فرض دکمه «برگشتن» را لغو کنید تا کاربر بتواند به‌جای صفحه‌های قبلی در برنامه‌تان، در سابقه مرور وب خود به عقب پیمایش کند.

پیاده‌سازی پیمایش به عقب سفارشی در Compose

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

هنگام استفاده از Navigation Compose، معمولاً از NavController.navigateUp() یا NavController.popBackStack() برای پیمایش به صفحه قبلی در پشته قبلی‌ها استفاده می‌کنید. بااین‌حال، BackHandler برای مواردی که می‌خواهید وقتی کاربر دکمه برگشت سیستم را فشار می‌دهد یا از اشاره برگشت استفاده می‌کند، رفتار سفارشی پیاده‌سازی کنید مفید است. برای مثال، اگر WebView را در برنامه‌تان نمایش می‌دهید، شاید بخواهید به کاربران اجازه دهید وقتی دکمه برگشتن سیستم را فشار می‌دهند، در سابقه مرور به عقب برگردند.

استفاده پایه

در اینجا مثالی از نحوه رهگیری رویداد برگشت برای کنترل وضعیت سفارشی (مانند جمع کردن پانل) آورده شده است:

@Composable
fun MyScreen() {
    var isExpanded by remember { mutableStateOf(false) }

    // Intercept the back button or gesture only when isExpanded is true
    BackHandler(enabled = isExpanded) {
        // Collapsing the content disables this handler, so it does not
        // receive the next back event.
        isExpanded = false
    }

    if (isExpanded) {
        Text("Expanded content. Go back to collapse it.")
    } else {
        Button(onClick = { isExpanded = true }) {
            Text("Expand")
        }
    }
}

رهگیری درخت ساختنی

اگر چند BackHandler ترکیب‌پذیر فعال در سطوح مختلف درخت ترکیب‌پذیرتان داشته باشید، فقط داخلی‌ترین آن‌ها رویداد برگشت را رهگیری می‌کند.

پیاده‌سازی پیمایش به عقب سفارشی با «نماها»

‫ComponentActivity، کلاس پایه برای FragmentActivity و AppCompatActivity، به شما امکان می‌دهد بااستفاده از OnBackPressedDispatcher آن، که می‌توانید با فراخوانی getOnBackPressedDispatcher() بازیابی کنید، رفتار دکمه «برگشت» را کنترل کنید.

OnBackPressedDispatcher نحوه ارسال رویدادهای دکمه «برگشتن» به یک یا چند شیء OnBackPressedCallback را کنترل می‌کند. سازنده برای OnBackPressedCallback یک مقدار بولی برای وضعیت فعال اولیه می‌گیرد. فقط وقتی فراخوانی برگشتی فعال باشد، مثلاً وقتی isEnabled() مقدار true را برمی‌گرداند، توزیع‌کننده handleOnBackPressed() فراخوانی برگشتی را برای رسیدگی به رویداد دکمه «برگشتن» فراخوانی می‌کند. می‌توانید با فراخوانی setEnabled()، وضعیت فعال را تغییر دهید.

بازتماس‌ها بااستفاده از روش‌های addCallback اضافه می‌شوند. از روش addCallback() استفاده کنید که LifecycleOwner را می‌گیرد. به این ترتیب، OnBackPressedCallback فقط زمانی اضافه می‌شود که LifecycleOwner Lifecycle.State.STARTED باشد. این فعالیت همچنین وقتی LifecycleOwner منسوب به آن ازبین می‌رود، کاربران ثبت‌شده را برمی‌دارد که از نشت حافظه جلوگیری می‌کند و آن را برای استفاده در قطعه‌ها یا مالکان چرخه حیات دیگر که طول عمر کوتاه‌تری نسبت‌به فعالیت دارند مناسب می‌کند.

در اینجا نمونه‌ای از پیاده‌سازی فراخوانی برگشتی آورده شده است:

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback will only be called when MyFragment is at least Started.
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

می‌توانید بااستفاده از addCallback() چندین تماس برگشتی ارائه دهید. وقتی این کار را انجام می‌دهید، توابع برگشتی به ترتیبی معکوس نسبت‌به ترتیبی که اضافه شده‌اند فراخوانی می‌شوند—تابع برگشتی که آخر از همه اضافه شده است اولین تابعی است که فرصت رسیدگی به رویداد دکمه «بازگشت» را پیدا می‌کند. برای مثال، اگر سه پاسخ‌به‌تماس با نام‌های one، two، و three را به ترتیب اضافه کنید، این پاسخ‌به‌تماس‌ها به ترتیب three، two، و one فراخوانی می‌شوند.

بازخوان‌ها از الگوی زنجیره مسئولیت پیروی می‌کنند. هر فراخوانی برگشتی در زنجیره فقط درصورتی فراخوانی می‌شود که فراخوانی برگشتی قبلی فعال نشده باشد. این یعنی در مثال قبلی، فراخوانی برگشتی two فقط درصورتی فراخوانده می‌شود که فراخوانی برگشتی three فعال نباشد. فراخوانی one فقط درصورتی فراخوانده می‌شود که فراخوانی two فعال نشده باشد، و این الگو برای هر فراخوانی اضافی ادامه می‌یابد.

توجه داشته باشید که وقتی بااستفاده از addCallback() اضافه می‌شود، فراخوان برگشتی به زنجیره مسئولیت اضافه نمی‌شود تا زمانی که LifecycleOwner وارد حالت Lifecycle.State.STARTED شود.

برای تغییرات موقت، تغییر وضعیت فعال در تماس برگشتی به‌شدت توصیه می‌شود زیرا ترتیب شرح‌داده‌شده در بالا را حفظ می‌کند، که به‌ویژه اگر تماس‌های برگشتی ثبت‌شده در چند مالک چرخه حیات تو در تو داشته باشید اهمیت دارد.

اگر می‌خواهید تماس برگشتی را کاملاً بردارید، با remove() تماس بگیرید. این کار معمولاً لازم نیست زیرا وقتی LifecycleOwner مربوط به فراخوانی‌های برگشتی ازبین می‌رود، فراخوانی‌های برگشتی به‌طور خودکار برداشته می‌شوند.