بازگرداندن تمرکز

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

بازیابی تمرکز در محفظه‌های پیمایش‌پذیر

در Jetpack Compose، محتویات پیمایش‌پذیر مثل LazyColumn، LazyRow، و LazyVerticalGrid به‌طور خودکار به‌عنوان گروه‌های کانونی عمل می‌کنند. برای فعال کردن بازیابی تمرکز در فهرست یا جدولی تنبل، اصلاح‌گر focusRestorer را پیوست کنید:

LazyColumn(
    modifier = Modifier.focusRestorer()
) {
    items(items) { item ->
        Button(onClick = { /* Handle click */ }) {
            Text(item)
        }
    }
}

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

بازیابی تمرکز در «ردیف» و «ستون»

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

برای فعال کردن بازگرداندن تمرکز در Row یا Column، focusGroup را با focusRestorer ترکیب کنید:

Row(
    modifier = Modifier
        .focusGroup()
        .focusRestorer()
) {
    Button(onClick = { /* Action 1 */ }) {
        Text("First item")
    }
    Button(onClick = { /* Action 2 */ }) {
        Text("Second item")
    }
    Button(onClick = { /* Action 3 */ }) {
        Text("Third item")
    }
}

هدف کانونی جایگزینی را مشخص کنید

وقتی تمرکز برای اولین‌بار وارد یک محتوی می‌شود، هیچ فرزند قبلاً کانونی‌شده‌ای وجود ندارد. «ترکیب» از ترتیب فوکوس پیش‌فرض برای تعیین اینکه کدام فرزند را در فوکوس قرار دهد پیروی می‌کند.

می‌توانید با ارسال بازگشتی FocusRequester به focusRestorer (یا لامبدایی که FocusRequester را در نسخه‌های قدیمی‌تر Compose برمی‌گرداند)، سفارشی‌سازی کنید که کدام کودک در اولین ورودی تمرکز داشته باشد:

val firstItemRequester = remember { FocusRequester() }

LazyColumn(
    modifier = Modifier.focusRestorer(firstItemRequester)
) {
    itemsIndexed(items) { index, item ->
        val itemModifier = if (index == 0) {
            Modifier.focusRequester(firstItemRequester)
        } else {
            Modifier
        }
        Button(
            onClick = { /* Handle click */ },
            modifier = itemModifier
        ) {
            Text(item)
        }
    }
}

اگر قبلاً هیچ کودکی در کانون توجه قرار نگرفته باشد (یا اگر بازیابی کانون توجه ناموفق باشد)، «نوشتن» کانون توجه را به هدف جایگزین مرتبط منتقل می‌کند.

در عناصر پیمایش مثل NavigationRail، NavigationBar، NavigationDrawer، یا TabRow، کاربران انتظار دارند وقتی از ناحیه محتوا وارد عنصر می‌شوند، تمرکز روی مقصد انتخاب‌شده فعلی قرار گیرد.

با ترکیب کردن Modifier.focusGroup() با focusProperties و تنظیم کردن دارایی onEnter (یا enter در نسخه‌های قدیمی‌تر «نوشتن»): می‌توانید تمرکز را به مقصد فعال هدایت کنید:

val (homeRequester, searchRequester, settingsRequester) = remember { FocusRequester.createRefs() }

val selectedRequester = when (currentDestination) {
    "home" -> homeRequester
    "search" -> searchRequester
    "settings" -> settingsRequester
    else -> homeRequester
}

NavigationRail(
    modifier = modifier
        .focusProperties {
            // Redirect focus to the selected item when focus enters the navigation rail
            onEnter = { selectedRequester.requestFocus() }
        }
        .focusGroup()
) {
    NavigationRailItem(
        selected = currentDestination == "home",
        onClick = { onNavigate("home") },
        icon = { Icon(Icons.Default.Home, contentDescription = "Home") },
        label = { Text("Home") },
        modifier = Modifier.focusRequester(homeRequester)
    )
    NavigationRailItem(
        selected = currentDestination == "search",
        onClick = { onNavigate("search") },
        icon = { Icon(Icons.Default.Search, contentDescription = "Search") },
        label = { Text("Search") },
        modifier = Modifier.focusRequester(searchRequester)
    )
    NavigationRailItem(
        selected = currentDestination == "settings",
        onClick = { onNavigate("settings") },
        icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") },
        label = { Text("Settings") },
        modifier = Modifier.focusRequester(settingsRequester)
    )
}

بازگرداندن تمرکز در انتقال‌های صفحه

وقتی کاربر روی موردی کلیک می‌کند تا به صفحه جزئیات پیمایش کند و سپس بااستفاده از دکمه یا اشاره «برگشتن» برمی‌گردد، می‌توانید فوکوس را به موردی که کاربر روی آن کلیک کرده است برگردانید.

برای حفظ و بازیابی تمرکز در انتقال‌های صفحه:

  1. ظرف را با FocusRequester مرتبط کنید.
  2. قبل‌از راه‌اندازی رویداد پیمایش، saveFocusedChild() را در FocusRequester محتوی فراخوانی کنید.
  3. وقتی کاربر به صفحه برمی‌گردد، تمرکز اولیه را روی ظرف درخواست کنید یا restoreFocusedChild() را فراخوانی کنید.