我正在使用 BrightScript 和 SceneGraph 开发 Roku 应用程序。我有一个海报网格,用户可以在多个海报之间进行选择。当用户选择一个时,将调用 ShowTopicScreen 子函数:
显示主题屏幕.brs
sub ShowTopicScreen(topic as Object)
topicScreen = CreateObject("roSGNode", "TopicScreen")
topicScreen.content = topic
topicScreen.ObserveField("visible", "OnDetailsScreenVisibilityChanged")
ShowScreen(topicScreen)
end sub
sub OnTopicScreenVisibilityChanged(event as Object)
visible = event.GetData()
currentScreen = GetCurrentScreen()
screenType = currentScreen.SubType()
if visible = false
if screenType = "HomeScreen"
currentScreen.jumpToItem = m.selectedTopicIndex
end if
end if
end sub
主题屏幕应该读取内容数据并填充标签并将某些数据加载到行列表(仍在开发中)
主题屏幕.xml
<?xml version="1.0" encoding="UTF-8"?>
<component name="TopicScreen" extends="Group" initialFocus="topicList">
<script type="text/brightscript" uri="TopicScreen.brs" />
<interface>
<!-- Specifies the content for the Grid -->
<field id="content" type="assocarray" />
<field id="topiccontent" type="node" alias="topicList.content" />
<field id="rowItemSelected" type="intarray" alwaysnotify="true" alias="topicList.rowItemSelected" />
<field id="jumpToRowItem" type="intarray" alias="topicList.jumpToRowItem" />
</interface>
<children>
<Label
id="titleLabel"
width="1020"
translation="[105,170]"
/>
<Label
id="textLabel"
width="1020"
translation="[105,190]"
text="A test label"
/>
<RowList
itemComponentName="TopicRowListItemComponent"
id="topicList"
translation="[105,240]"
numRows="2"
rowitemSize="[[320,180]]"
rowItemSpacing="[[20,0]]"
itemSize="[1100,270]"
rowLabelOffset="[[50,20]]"
focusXOffset="[50]"
showRowLabel="[true]"
rowFocusAnimationStyle="floatingfocus"
/>
</children>
</component>
主题屏幕.brs
sub Init()
m.top.observeField("visible", "onVisibleChange")
m.titleLabel = m.top.FindNode("titleLabel")
end sub
sub onVisibleChange()
'this only runs when I leave the screen
if m.top.visible = true
SetContent()
end if
end sub
sub SetContent()
m.titleLabel = m.top.topic.title
end sub
问题是 OnVisibleChange 子组件永远不会被调用(当我按后退按钮转到第一个屏幕时,它会被调用,但是,如果我返回到主题屏幕,它又不会被调用)。 TopicScreen 正在加载,因为我可以在屏幕上看到静态标签(“测试标签”)。
为什么 OnVisibleChange() 子函数没有被调用以及如何获取数据来填充标签?
仅当
visible
字段从一个值更改为另一个值时,您的观察者才会被触发,除非您已将该字段的 notifyAlways
定义为 true,但无论如何,观察者回调都会在分配 visible
值后触发。我在代码中没有看到您如何分配 visible
值。
也许您想观察
renderTracking
?请参阅Group 类参考中的更多详细信息。
sub init()
(...)
m.top.enableRenderTracking = true
m.top.observeField("renderTracking", "onVisibilityChange")
end sub
sub onVisibilityChange()
if m.top.renderTracking = "full" ' Based on your needs you might want to check for "partial" as well.
(...)
end if
end sub
sub Init()
m.top.observeFieldScoped("visible", "onVisibleChange")
m.titleLabel = m.top.FindNode("titleLabel")
end sub
sub onVisibleChange(event as Object)
' Check if the visibility change event is triggered by setting content
if m.top.visible = true and not m.settingContent
SetContent()
end if
end sub
sub SetContent()
m.titleLabel.text = m.top.topic.title
' Add a flag to indicate that content is being set
m.settingContent = true
' After setting content, reset the flag
m.settingContent = false
end sub
所做的更改:
使用 observeFieldScoped 而不是 observeField 以确保正确 范围界定。
添加了一个标志(m.settingContent)以防止递归。当你设置 SetContent 中的内容,可能会触发可见性的变化, 在这种情况下,我们希望避免再次调用 SetContent。
这个调整应该确保当可见性改变时触发onVisibleChange函数,并且它设置内容而不引起递归。