最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Focus not clearing jetpack compose android tv - Stack Overflow

programmeradmin2浏览0评论

so i have an android tv project and my structure is like this

TvLazyColumn(
                state = listState,
                pivotOffsets = PivotOffsets(0.15F),
                modifier = Modifier
                    .focusRequester(setFocusContinueWatch)
                    .onKeyEvent {
                        if (it.nativeKeyEvent.action == KeyEvent.ACTION_DOWN) {
                            when (it.nativeKeyEvent.keyCode) {
                                KeyEvent.KEYCODE_DPAD_UP -> {
                                    if (selectedRow > 0) {
                                        selectedRow--
                                        isUpFromList = false
                                    } else {
                                        isUpFromList = true
                                        setFocusContinueWatch.freeFocus()
                                        isFocusOnListing = false

                                    }
                                }

                                KeyEvent.KEYCODE_DPAD_DOWN -> {
                                    if (selectedRow < sizeOfRows!!) {
                                        selectedRow++
                                        isFocusOnListing = true
                                        isUpFromList = false
                                    }
                                }
                            }
                        }
                        false
                    }

now above this i have 2 types of view one when focusonlisting and one on !focusonlisting so in case of !focusonlisting i have a button watchnowbutton. so i have a logic for indexing for gtting the selectedrow now when im at top row i press up and else block logic triggers

 LaunchedEffect(isFocusOnListing) {
                        if (isUpFromList) {
                            setFocusContinueWatch.freeFocus()
                            watchNowBtnFocus = true
                            setFocusOnWatchNow.captureFocus()
                        }
                    }

now what happens when i press up from fist row index 0 is the focus is on the button as the color of button changes onfocus but also the focus stays on the row as well as it shows the border and when moving left right i am moving left and right in the row. now i have to press up one more time to actually go to button.

so i have an android tv project and my structure is like this

TvLazyColumn(
                state = listState,
                pivotOffsets = PivotOffsets(0.15F),
                modifier = Modifier
                    .focusRequester(setFocusContinueWatch)
                    .onKeyEvent {
                        if (it.nativeKeyEvent.action == KeyEvent.ACTION_DOWN) {
                            when (it.nativeKeyEvent.keyCode) {
                                KeyEvent.KEYCODE_DPAD_UP -> {
                                    if (selectedRow > 0) {
                                        selectedRow--
                                        isUpFromList = false
                                    } else {
                                        isUpFromList = true
                                        setFocusContinueWatch.freeFocus()
                                        isFocusOnListing = false

                                    }
                                }

                                KeyEvent.KEYCODE_DPAD_DOWN -> {
                                    if (selectedRow < sizeOfRows!!) {
                                        selectedRow++
                                        isFocusOnListing = true
                                        isUpFromList = false
                                    }
                                }
                            }
                        }
                        false
                    }

now above this i have 2 types of view one when focusonlisting and one on !focusonlisting so in case of !focusonlisting i have a button watchnowbutton. so i have a logic for indexing for gtting the selectedrow now when im at top row i press up and else block logic triggers

 LaunchedEffect(isFocusOnListing) {
                        if (isUpFromList) {
                            setFocusContinueWatch.freeFocus()
                            watchNowBtnFocus = true
                            setFocusOnWatchNow.captureFocus()
                        }
                    }

now what happens when i press up from fist row index 0 is the focus is on the button as the color of button changes onfocus but also the focus stays on the row as well as it shows the border and when moving left right i am moving left and right in the row. now i have to press up one more time to actually go to button.

Share Improve this question edited Jan 19 at 18:33 tyg 14.9k4 gold badges34 silver badges47 bronze badges asked Jan 19 at 18:06 Priyanshu RajPriyanshu Raj 334 bronze badges 1
  • Based on the description, what you are trying to achieve is not super clear to me. Could you please attach screenshots of expected and actual behaviour? – vighnesh153 Commented Jan 20 at 4:45
Add a comment  | 

2 Answers 2

Reset to default 0

when you press up from the first row, you're getting a split focus state where both the button and the row appear to have focus, requiring an extra up press to fully move to the button.

Changes i made in your code:

1.Added true return values when handling UP/DOWN keys to consume events.

2.clear the row selection when moving up from the first row

3.Add a small delay in launcheffect.

This is your updated code with my comments:

TvLazyColumn(
state = listState,
pivotOffsets = PivotOffsets(0.15F),
modifier = Modifier
.focusRequester(setFocusContinueWatch)
.onKeyEvent {
    if (it.nativeKeyEvent.action == KeyEvent.ACTION_DOWN) {
        when (it.nativeKeyEvent.keyCode) {
            KeyEvent.KEYCODE_DPAD_UP -> {
                if (selectedRow > 0) {
                    selectedRow--
                    isUpFromList = false
                } else {
                    isUpFromList = true
                    setFocusContinueWatch.freeFocus()
                    // Clear the row selection when moving up*
                    selectedRow = -1
                    // Or another invalid value*
                    isFocusOnListing = false
                }
                true
                // Consume the event*
            }

            KeyEvent.KEYCODE_DPAD_DOWN -> {
                if (selectedRow < sizeOfRows!!) {
                    selectedRow++
                    isFocusOnListing = true
                    isUpFromList = false
                }
                true
                // Consume the event*
            }

            else -> false
        }
    } else false
}
)

Change this in Launcheffect:

LaunchedEffect(isFocusOnListing) {
    if (isUpFromList) {
        // Ensure complete focus transfer
        setFocusContinueWatch.freeFocus()
        delay(50) // Small delay to ensure focus release
        watchNowBtnFocus = true
        setFocusOnWatchNow.captureFocus()
    }
} 

Finally in Button you can add this for focus change:

  Button(
        modifier = Modifier
            .focusRequester(setFocusOnWatchNow)
            .onFocusChanged { state ->
                watchNowBtnFocus = state.isFocused
                if (state.isFocused) {
                    isFocusOnListing = false
                }
            }
    )

so i got the solution

KeyEvent.KEYCODE_DPAD_UP -> {
                                    if (selectedRow > 0) {
                                        selectedRow--
                                        isUpFromList = false
                                    } else {
                                        scope.launch{
                                            isFocusOnListing = false
                                            isUpFromList = true
                                            delay(50)
                                            setFocusContinueWatch.freeFocus()
                                            setFocusOnWatchNow.requestFocus()
                                        }
                                    }

i just did the whole operation in a coroutine scope and added a 50milli delay

发布评论

评论列表(0)

  1. 暂无评论