如何在Bixby Capsule中实现每秒刷新的秒表(计时器)?
Hey there! I’ve built a stopwatch feature for Bixby Capsules before, so I can walk you through exactly how to pull this off—including that critical auto-refresh every second.
Core Idea
Bixby’s UI updates reactively to changes in your capsule’s data model. So we’ll track the stopwatch state (start time, elapsed seconds, running status) in a model, then use a recurring timer to update that model every second. This will automatically trigger the view to refresh without any manual DOM manipulation.
Step-by-Step Implementation
1. Define the Stopwatch Data Model
First, create a structure to hold all the stopwatch state. Add this to your models folder:
structure Stopwatch { property startTime as Time? property elapsedSeconds as Integer property isRunning as Boolean }
This tracks when the stopwatch started, how many seconds have passed, and whether it’s actively running.
2. Build Timer Logic with Actions
We need two key actions: one to toggle start/stop, and another to update the elapsed time every second.
Toggle Start/Stop Action
Create a ToggleStopwatch action to handle starting and pausing the stopwatch. Here’s the JavaScript implementation:
module.exports.function = function toggleStopwatch(stopwatch) { stopwatch.isRunning = !stopwatch.isRunning; if (stopwatch.isRunning) { // Record start time when starting stopwatch.startTime = new Date().toISOString(); stopwatch.elapsedSeconds = 0; } return stopwatch; }
Recurring Update Action
Create an UpdateStopwatch action that calculates the elapsed time and updates the model:
action UpdateStopwatch { type(Synchronous) output(Stopwatch) }
And its JavaScript logic:
module.exports.function = function updateStopwatch(stopwatch) { if (!stopwatch.isRunning) { return stopwatch; // Do nothing if stopped } const now = new Date(); const elapsedMs = now - new Date(stopwatch.startTime); stopwatch.elapsedSeconds = Math.floor(elapsedMs / 1000); return stopwatch; }
3. Set Up the Scene with a Timer
In your scene, configure a recurring timer to call UpdateStopwatch every 1 second when the stopwatch is running. Don’t forget to cancel the timer when exiting the scene to save resources:
scene StopwatchScene { template("Stopwatch View") on-entry { intent { goal: StartStopwatch // Initialize stopwatch state if needed } } on-active { timer { id("stopwatchRefresh") interval(1s) intent { goal: UpdateStopwatch value: $vivContext.stopwatch } } } on-exit { cancel-timer(id("stopwatchRefresh")) // Clean up timer when leaving } }
4. Build the Auto-Refreshing View
Create a view that binds to the elapsedSeconds property. Bixby will automatically refresh the view whenever the model updates. Add a helper function to format seconds into a readable MM:SS format:
View Code
view { layout { section { content { text { value("#{formatTime($stopwatch.elapsedSeconds)}") style(H1) alignment(Center) } } } section { content { button { text(if ($stopwatch.isRunning) "Stop" else "Start") on-press { intent { goal: ToggleStopwatch } } style(Primary) alignment(Center) } } } } }
Formatting Helper
Add this function to your JavaScript utilities to format the time:
function formatTime(seconds) { const mins = Math.floor(seconds / 60); const secs = seconds % 60; // Pad with leading zeros for clean display return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; }
Key Tips
- Always cancel the timer when exiting the scene to prevent unnecessary background processing.
- Test pause/resume flow to ensure elapsed time calculates correctly (the start time is only updated when starting fresh, not resuming).
- Bixby’s reactive views mean you don’t need to manually trigger refreshes—any change to the
Stopwatchmodel will update the UI automatically.
内容的提问来源于stack exchange,提问作者Rahul Gupta

