# 如何实现自定义UI单选功能

#### 问题现象

实现一个单选组件，要求：①绘制指示图标，②选中项需显示高亮状态。

效果预览：

#### 效果预览

#### 背景知识

*   Polygon：多边形绘制组件。
*   Stack：堆叠容器，子组件按照顺序依次入栈，后一个子组件覆盖前一个子组件。

#### 解决方案

采用Stack容器实现层叠布局，通过@State变量控制Polygon绘制的三角形指示图标显示与隐藏状态，结合条件渲染，实现选中时的高亮切换效果。

```
@Entry
@Component
struct RadioPage {
  @State select: string = 'SELECT_OPTION_1'; // SELECT_OPTION_1为选项一，SELECT_OPTION_2为选项二

  @Builder
  commonUI(selectValue:string,imageUrl:string,context:string) {
    Stack() {
      Row() {
        Image($r(imageUrl))
          .width(40)
          .height(40)
        Text(context)
      }
      .width(150)
      .padding(5)
      .borderRadius(5)
      .border({ width: 1, color: this.select === selectValue ? '#ff5892de' : '#ffc4cac7' }) // 根据select变量判断选中的border颜色
      .backgroundColor(this.select === selectValue? '#ff5892de' : '#ffc4cac7') // 根据select变量判断选中的backgroundColor颜色
      .justifyContent(FlexAlign.Center)

      if (this.select === selectValue) {
        // 三角形指示图标
        Polygon({ width: 20, height: 20 })
          .points([[10, 10], [15, 0], [20, 10]])
          .fill('#ff5892de')
          .position({ top: -10, left: 10 })
      }
    }
    .onClick(() => {
      this.select = selectValue;
    })
  }

  build() {
    Column() {
      Flex({ justifyContent: FlexAlign.SpaceBetween }) {
        // 选项一
        this.commonUI('SELECT_OPTION_1','app.media.startIcon','选项一');
        // 选项二
        this.commonUI('SELECT_OPTION_2','app.media.startIcon','选项二');
      }
      .padding(10)
      .height(100)
      .width('100%')
    }
  }
}
```