Read the original article:Designing a Two-Segment Toggle with Color Swap in HarmonyOS
Designing a Two-Segment Toggle with Color Swap in HarmonyOS
Requirement Description
Implement a two-option button (e.g., EURO/USD) where tapping either side toggles both background and font colors between the two segments.
Background Knowledge
- SegmentButton: segmented control with tab/single/multi-select variants.
Docs: https://developer.huawei.com/consumer/en/doc/harmonyos-references/ohos-arkui-advanced-segmentbutton
- TabSegmentButtonConstructionOptions: build options for tab-style SegmentButton, including colors and paddings.
- borderRadius: sets corner radius (max = half of width/height).
Implementation Steps
-
Decide control approach
-
Option A (built-in): use
SegmentButtonfor fastest integration. -
Option B (custom): compose two
Text(orButton) nodes in a rounded container; toggle styles via a boolean state.
-
Option A (built-in): use
-
Define visual states
- Active side: white background + dark text (or vice-versa), rounded inner pill.
- Inactive side: outline or contrasting fill + brand color text.
-
Wire interactions
- Update selected index (Option A) or
isEnableboolean (Option B) on tap.
- Update selected index (Option A) or
-
Wearable tweaks (recommended)
- Ensure minimum 44 vp touch target per side, adequate padding, and high contrast for indoor/outdoor readability.
-
Validate
- Verify color swap, radius, and RTL behavior; confirm code check passes.
Code Snippet / Configuration
Option A — SegmentButton (quickest)
import { LengthMetrics, SegmentButton, SegmentButtonOptions } from '@kit.ArkUI'
@Entry
@Component
struct Index {
@State tabOptions: SegmentButtonOptions = SegmentButtonOptions.tab({
buttons: [{ text: 'Dollar' }, { text: 'Euro' }],
direction: Direction.Rtl,
backgroundColor: Color.Red,
selectedBackgroundColor: Color.White,
selectedFontColor: Color.Black,
localizedTextPadding: { end: LengthMetrics.vp(10), start: LengthMetrics.vp(10) }
})
@State tabSelectedIndexes: number[] = [0]
build() {
Row() {
Column() {
Column({ space: 20 }) {
SegmentButton({ options: this.tabOptions, selectedIndexes: $tabSelectedIndexes })
}.width('100%')
}.width('100%')
}.height('100%')
}
}
Note: selectedFontColor applies uniformly to all selected buttons; per-tab font colors are not independently configurable here.
Option B — Custom rounded toggle (full control)
@Entry
@Component
struct SegmentButtonTest {
@State isEnable: boolean = true
build() {
Column() {
Blank().height('25%')
Row() {
Text('Dollar')
.fontSize(14)
.fontColor(this.isEnable ? '#fff' : '#F44837')
.backgroundColor(this.isEnable ? '#FF4C30' : '#fff')
.borderRadius(this.isEnable ? 20 : 0)
.padding(6)
.width(60)
.borderRadius(20)
.height(40)
.onClick(() => this.isEnable = true)
Text('Euro')
.fontSize(14)
.fontColor(!this.isEnable ? '#fff' : '#F44837')
.backgroundColor(!this.isEnable ? '#FF4C30' : '#fff')
.borderRadius(!this.isEnable ? 20 : 0)
.padding(6)
.width(66)
.borderRadius(20)
.height(40)
.onClick(() => this.isEnable = false)
}
.height(40)
.margin(28)
.backgroundColor('#fff')
.border({ width: 4 })
.borderColor('#F44837')
.borderRadius(20)
}
.height('100%')
.width('100%')
}
}
Test Results
- Visual and interaction behavior matches the target GIFs for both options.
- Code Check passes (screenshots provided).
Limitations or Considerations
-
SegmentButton:
selectedFontColoris global for selected tabs; you can’t set different selected font colors for left/right simultaneously. - Custom toggle: a bit more code, but you get full per-segment styling control (colors, radius, states).
- Ensure contrast ratios and 44 vp touch targets for wearables; verify on round screens to avoid clipped radii.
Related Documents or Links
- SegmentButton: https://developer.huawei.com/consumer/en/doc/harmonyos-references/ohos-arkui-advanced-segmentbutton
- TabSegmentButtonConstructionOptions: https://developer.huawei.com/consumer/en/doc/harmonyos-references/ohos-arkui-advanced-segmentbutton#tabsegmentbuttonconstructionoptions
- borderRadius: https://developer.huawei.com/consumer/en/doc/harmonyos-references/ts-universal-attributes-border#borderradius


Top comments (0)