You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Roku中RowList失焦时移位缩表现象的消除方案问询

问题:RowList自定义组件失焦时出现偏移与尺寸异常

我基于RowList扩展了名为horizontal-list的自定义组件,并在LayoutGroup中使用该组件的多个实例,每个列表包含一行尺寸一致的内容。目前通过监听按键事件手动处理不同列表间的焦点切换,但遇到异常问题:未获得焦点的列表会向右偏移约20像素并明显缩小尺寸,获得焦点后恢复原位及原尺寸。我尝试修改rowFocusAnimationStyle、vertFocusAnimationStyle、focusXOffset等属性,但均无法解决,希望消除该异常行为。


BrightScript实现代码

function init()
    m.top.focusable = true
    m.top.itemComponentName = "SimpleCard"
    m.top.numRows = 1
    m.top.showRowLabel = true
    m.top.drawFocusFeedback = true
    m.top.vertFocusAnimationStyle = "fixedFocus"
    m.top.rowFocusAnimationStyle = "fixedFocus"
    m.top.rowLabelOffset = [[0, 20]]
    m.top.rowLabelFont = "font:MediumBoldSystemFont"
    m.top.focusBitmapUri = "pkg:/images/focus_25x25_2_0.9.png"
    m.top.rowItemSpacing = [[20, 0]]
    m.top.numRows = 1
    m.top.itemSize = [1500, 500]
    m.top.showRowLabel = [true]

    m.top.observeField("focusedChild", "onFocusChanged")
    m.top.observeField("playlistUrl", "onPlaylistUrlChange")
    m.top.observeField("showTitle", "onShowTitleChanged")
    m.top.observeField("cardStyle", "onCardStyleChange")
    m.top.observeField("titleKey", "onTitleKeyChange")
    m.top.observeField("padding", "onPaddingChange")

    m.playlistData = invalid
end function

function onPlaylistApiResponse()
    m.playlistData = m.playlistTask.response
    populateList()
    updateRowTitle()
end function

function onPlaylistApiError()
    print "Error loading playlist."
end function

sub onCardStyleChange()
    if m.top.cardStyle <> invalid
        populateList()
    end if
end sub

function populateList() as void
    if m.playlistData = invalid or m.top.cardStyle = invalid then return

    entries = m.playlistData.entry
    if entries.count() = 0 then
        ? "No entries in playlist."
        return
    end if

    cardSize = getCardSize(entries)
    cardWidth = cardSize.width
    cardHeight = cardSize.height

    m.top.itemSize = [m.top.itemSize[0], cardHeight + m.top.rowLabelOffset[0][1] + m.top.rowLabelFont.size + 10]

    m.top.rowItemSize = [[cardWidth, cardHeight]]

    m.rowContent = CreateObject("roSGNode", "ContentNode")
    m.top.content = m.rowContent

    m.row = CreateObject("roSGNode", "ContentNode")

    m.row.title = m.playlistData.title
    m.rowContent.appendChild(m.row)

    for each entry in entries
        cardContent = CreateObject("roSGNode", "CardContentNode")
        cardContent.playListItem = entry
        if m.top.cardStyle <> invalid and m.top.cardStyle.cardStyle <> invalid
            cardContent.styles = m.top.cardStyle.cardStyle
        end if
        m.row.appendChild(cardContent)
    end for
end function

function getCardSize(entries as object) as object
    tempCard = createObject("roSGNode", "SimpleCard")
    tempCard.visible = false
    m.top.appendChild(tempCard)

    firstItem = entries[0]
    firstCardContent = CreateObject("roSGNode", "CardContentNode")
    firstCardContent.playListItem = firstItem
    if m.top.cardStyle <> invalid and m.top.cardStyle.cardStyle <> invalid
        firstCardContent.styles = m.top.cardStyle.cardStyle
    end if

    tempCard.itemContent = firstCardContent

    cardHeight = tempCard.boundingRect().height
    cardWidth = tempCard.boundingRect().width

    m.top.removeChild(tempCard)

    return { width: cardWidth, height: cardHeight }
end function

function onKeyEvent(key as string, press as boolean) as boolean
    if press = false
        return false
    end if

    if key = "OK" then
        focusedItem = m.row.getChild(m.top.rowItemFocused[1])
        if focusedItem <> invalid
            focusedItem.isSelected = true
        end if
        return true
    end if

    return false
end function

' Property Observers
function onPlaylistUrlChange()
    if m.top.playlistUrl <> ""
        m.playlistTask = createObject("roSGNode", "APITask")
        m.playlistTask.observeField("response", "onPlaylistApiResponse")
        m.playlistTask.observeField("error", "onPlaylistApiError")
        m.playlistTask.url = m.top.playlistUrl
        m.playlistTask.control = "run"
    end if
end function

sub onShowTitleChanged()
    m.top.showRowLabel = [m.top.showTitle]
end sub

sub updateRowTitle()
    if m.playlistData <> invalid and m.top.titleKey <> invalid and m.top.titleKey <> "" then
        titleValue = m.playlistData.Lookup(m.top.titleKey)
        if titleValue <> invalid and m.row <> invalid
            m.row.title = titleValue
        end if
    end if
end sub

sub onTitleKeyChange()
    updateRowTitle()
end sub

sub onPaddingChange()
    if m.top.padding <> invalid
        if m.top.padding.left <> invalid and m.top.padding.left >= 0
            m.top.focusXOffset = [m.top.padding.left]
            m.top.rowLabelOffset = [[m.top.padding.left, m.top.rowLabelOffset[0][1]]]
        end if
    end if
end sub

XML组件定义

<?xml version="1.0" encoding="UTF-8"?>
<component name="horizontal-list" extends="RowList">

    <script type="text/brightscript" uri="HorizontalList.brs" />
    <script type="text/brightscript" uri="pkg:/source/core/Utils.brs" />

    <interface>
        <field id="playlistUrl" type="string" />
        <field id="cardStyle" type="assocarray" />
        <field id="showTitle" type="boolean" value="true" />
        <field id="titleKey" type="string" />
        <field id="margin" type="assocarray" />
        <field id="padding" type="assocarray" />
    </interface>

    <children />

</component>

内容的提问来源于stack exchange,提问作者Govardhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 05:40:05