ফোকাস রিস্টোর করা

ব্যবহারকারীরা হার্ডওয়্যার কীবোর্ড বা D-প্যাড ব্যবহার করে জটিল ইউজার ইন্টারফেস নেভিগেট করার সময়, তারা প্রায়ই স্ক্রিনের বিভিন্ন অংশের মধ্যে ঘুরে বেড়ান—যেমন সাইড নেভিগেশন রেল থেকে কন্টেন্ট লিস্টে যাওয়া, কোনও আইটেমের সাথে ইন্টার‍্যাক্ট করা এবং তারপরে আবার ফিরে আসা। ফোকাস রিস্টোরেশন কন্টেনারকে আগে ফোকাস করা চাইল্ড এলিমেন্ট মনে রাখতে এবং কন্টেনারে ফোকাস আবার এলে সেটি রিস্টোর করতে দেয়।

স্ক্রল করা যায় এমন কন্টেনারে ফোকাস ফিরিয়ে আনা

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")
    }
}

ফলব্যাক ফোকাস টার্গেট নির্দিষ্ট করুন

ফোকাস প্রথমবার কোনও কন্টেনারে প্রবেশ করলে, আগে ফোকাস করা কোনও চাইল্ড আর থাকে না। কোন চাইল্ডকে ফোকাস করা হবে তা নির্ধারণ করতে কম্পোজ ডিফল্ট ফোকাস অর্ডার অনুসরণ করে।

প্রথম এন্ট্রি করার সময় কোন চাইল্ড ফোকাস পাবে তা আপনি কাস্টমাইজ করতে পারেন। এর জন্য focusRestorer-এ (অথবা আগের Compose ভার্সনে FocusRequester রিটার্ন করা ল্যাম্বডা) একটি ফলব্যাক FocusRequester পাস করুন:

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-এর মতো নেভিগেশন কম্পোনেন্টে, কন্টেন্ট এরিয়া থেকে কম্পোনেন্টে প্রবেশ করার সময় ব্যবহারকারীরা চান যে ফোকাস যেন বর্তমানে বেছে নেওয়া গন্তব্যে যায়।

আপনি focusProperties-এর সাথে Modifier.focusGroup() যোগ করে এবং onEnter প্রপার্টি (বা আগের Compose ভার্সনে 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. নেভিগেশন ইভেন্ট ট্রিগার করার আগে, কন্টেনারের FocusRequester-এ saveFocusedChild() কল করুন।
  3. ব্যবহারকারী স্ক্রিনে ফিরে এলে, কন্টেনারে প্রাথমিক ফোকাস করার অনুরোধ করুন অথবা restoreFocusedChild() কল করুন।