بازیابی تمرکز

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

بازیابی فوکوس در کانتینرهای قابل اسکرول

در Jetpack Compose، کانتینرهای قابل اسکرول مانند LazyColumn ، LazyRow و LazyVerticalGrid به طور خودکار به عنوان گروه‌های فوکوس عمل می‌کنند. برای فعال کردن بازیابی فوکوس در یک لیست یا شبکه‌ی lazy، اصلاح‌کننده‌ی 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")
    }
}

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

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

می‌توانید با ارسال یک 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)
        }
    }
}

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

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

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

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() را فراخوانی کنید.
{% کلمه به کلمه %} {% فعل کمکی %} {% کلمه به کلمه %} {% فعل کمکی %}