You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过BrightScript触发Roku返回操作?实现导航栈回退

如何用BrightScript触发Roku的返回操作(弹出当前屏幕回到上一屏)

当然可以实现!结合你现有的导航Task代码,我们只需要添加监听场景消息主动关闭当前屏幕的逻辑,就能完美满足你提到的两个场景需求。

核心原理

你当前的导航逻辑是每次跳转都创建新的roSGScreen和对应Scene,当roSGScreen被关闭时,handleNav的循环会退出,自然回到上一层的导航上下文(也就是之前的屏幕)。所以触发返回的核心就是主动关闭当前的roSGScreen实例


场景1:屏幕内返回按钮被点击触发返回

步骤1:在目标Scene的XML中添加返回按钮

比如在你的videoScreen对应的XML文件里,添加一个返回按钮控件:

<Button 
    id="backButton" 
    text="返回" 
    translation="[50, 50]" 
    width="200" 
    height="60"
/>

步骤2:在Scene的BrightScript中监听点击并发送返回指令

在Scene的init函数里绑定按钮点击事件,然后向NavigationTask的消息端口发送返回消息:

sub init()
    ' 获取NavigationTask的消息端口(需要提前传递给Scene)
    m.navigationPort = m.top.findNode("NavigationTask").port
    ' 监听返回按钮的点击事件
    m.top.findNode("backButton").observeField("buttonSelected", "onBackButtonClicked")
end sub

sub onBackButtonClicked()
    ' 发送关闭当前屏幕的消息到NavigationTask
    backMsg = CreateObject("roUniversalMessage")
    backMsg.SetMessage("closeCurrentScreen")
    m.navigationPort.SendMessage(backMsg)
end sub

步骤3:修改NavigationTask,监听消息并关闭屏幕

更新你的handleNav函数,添加对返回消息的监听,收到指令后主动关闭当前屏幕:

sub handleNav(sceneName as String)
    print "[NavigationTask] handleNav"
    screen = CreateObject("roSGScreen")
    m.port = createObject("roMessagePort")
    screen.SetMessagePort(m.port)
    if screen <> invalid
        scene = screen.CreateScene(sceneName)
        ' 将NavigationTask的端口传递给Scene,让Scene能发消息回来
        scene.SetField("navigationPort", m.port)
        screen.Show()
        
        while(true)
            msg = wait(0, m.port)
            msgType = type(msg)
            print "[NavigationTask] msg : "; msgType; " scene="sceneName
            
            ' 处理系统的屏幕关闭事件
            if msgType = "roSGScreenEvent"
                if msg.isScreenClosed() then
                    return
                end if
            ' 处理来自Scene的返回指令
            else if msgType = "roUniversalMessage"
                if msg.GetMessage() = "closeCurrentScreen" then
                    screen.Close() ' 主动关闭当前屏幕,触发返回
                    return
                end if
            end if
        end while
    else
        print "[NavigationTask] Invalid roSGScreen"
    end if
end sub

(顺便修正了你原代码里print语句的语法错误:少了一个分号)


场景2:特定回调事件触发返回

比如当播放结束、网络请求完成这类回调触发时,直接在回调函数里发送关闭屏幕的消息即可,逻辑和场景1完全一致:

sub onPlaybackFinished()
    ' 播放结束后触发返回操作
    backMsg = CreateObject("roUniversalMessage")
    backMsg.SetMessage("closeCurrentScreen")
    m.navigationPort.SendMessage(backMsg)
end sub

额外优化小建议

  • 可以封装一个通用的sendBackCommand函数,避免重复编写消息创建和发送的代码
  • 如果后续需要管理多层跳转的导航栈,可以在NavigationTask里维护一个栈结构记录屏幕信息,但对你当前的需求来说,关闭当前屏幕已经完全够用

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

火山引擎 最新活动