1# 按钮 (Button) 2 3 4Button是按钮组件,通常用于响应用户的点击操作,其类型包括胶囊按钮、圆形按钮、普通按钮、圆角矩形按钮。Button做为容器使用时可以通过添加子组件实现包含文字、图片等元素的按钮。具体用法请参考[Button](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md)。 5 6 7## 创建按钮 8 9Button通过调用接口来创建,接口调用有以下两种形式: 10 11 12- 通过label和[ButtonOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md#buttonoptions对象说明)创建不包含子组件的按钮。以ButtonOptions中的type和stateEffect为例。 13 14 ```ts 15 Button(label?: ResourceStr, options?: { type?: ButtonType, stateEffect?: boolean }) 16 ``` 17 18 其中,label用来设置按钮文字,type用于设置Button类型,stateEffect属性设置Button是否开启点击效果。 19 20 ```ts 21 Button('Ok', { type: ButtonType.Normal, stateEffect: true }) 22 .borderRadius(8) 23 .backgroundColor(0x317aff) 24 .width(90) 25 .height(40) 26 ``` 27 28  29 30 31- 通过[ButtonOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md#buttonoptions对象说明)创建包含子组件的按钮。以ButtonOptions中的type和stateEffect为例。 32 33 ```ts 34 Button(options?: {type?: ButtonType, stateEffect?: boolean}) 35 ``` 36 37 只支持包含一个子组件,子组件可以是基础组件或者容器组件。 38 39 ```ts 40 Button({ type: ButtonType.Normal, stateEffect: true }) { 41 Row() { 42 Image($r('app.media.loading')).width(20).height(40).margin({ left: 12 }) 43 Text('loading').fontSize(12).fontColor(0xffffff).margin({ left: 5, right: 12 }) 44 }.alignItems(VerticalAlign.Center) 45 }.borderRadius(8).backgroundColor(0x317aff).width(90).height(40) 46 ``` 47 48  49 50 51## 设置按钮类型 52 53Button有四种可选类型,分别为胶囊类型(Capsule)、圆形按钮(Circle)、普通按钮(Normal)和圆角矩形按钮(ROUNDED_RECTANGLE),通过type进行设置。 54 55 56- 胶囊按钮(默认类型)。 57 58 此类型按钮的圆角自动设置为高度的一半,不支持通过borderRadius属性重新设置圆角。 59 60 ```ts 61 Button('Disable', { type: ButtonType.Capsule, stateEffect: false }) 62 .backgroundColor(0x317aff) 63 .width(90) 64 .height(40) 65 ``` 66 67  68 69 70- 圆形按钮。 71 72 此类型按钮为圆形,不支持通过borderRadius属性重新设置圆角。 73 74 ```ts 75 Button('Circle', { type: ButtonType.Circle, stateEffect: false }) 76 .backgroundColor(0x317aff) 77 .width(90) 78 .height(90) 79 ``` 80 81  82 83- 普通按钮。 84 85 此类型的按钮默认圆角为0,支持通过borderRadius属性重新设置圆角。 86 87 ```ts 88 Button('Ok', { type: ButtonType.Normal, stateEffect: true }) 89 .borderRadius(8) 90 .backgroundColor(0x317aff) 91 .width(90) 92 .height(40) 93 ``` 94 95  96 97- 圆角矩形按钮 98 当[controlSize](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md#controlsize11)为NORMAL时,默认圆角大小为20vp,[controlSize](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md#controlsize11)为SMALL时,圆角大小为14vp,支持通过borderRadius属性重新设置圆角。 99 100 101 ```ts 102 Button('Disable', { type: ButtonType.ROUNDED_RECTANGLE, stateEffect: true }) 103 .backgroundColor(0x317aff) 104 .width(90) 105 .height(40) 106 ``` 107 108  109 110## 自定义样式 111 112- 设置边框弧度。 113 114 使用通用属性来自定义按钮样式。例如通过borderRadius属性设置按钮的边框弧度。 115 116 ```ts 117 Button('circle border', { type: ButtonType.Normal }) 118 .borderRadius(20) 119 .height(40) 120 ``` 121 122  123 124 125- 设置文本样式。 126 127 通过添加文本样式设置按钮文本的展示样式。 128 129 ```ts 130 Button('font style', { type: ButtonType.Normal }) 131 .fontSize(20) 132 .fontColor(Color.Pink) 133 .fontWeight(800) 134 ``` 135 136  137 138 139- 设置背景颜色。 140 141 添加backgroundColor属性设置按钮的背景颜色。 142 143 ```ts 144 Button('background color').backgroundColor(0xF55A42) 145 ``` 146 147  148 149 150- 创建功能型按钮。 151 152 为删除操作创建一个按钮。 153 154 ```ts 155 let MarLeft: Record<string, number> = { 'left': 20 } 156 Button({ type: ButtonType.Circle, stateEffect: true }) { 157 Image($r('app.media.ic_public_delete_filled')).width(30).height(30) 158 }.width(55).height(55).margin(MarLeft).backgroundColor(0xF55A42) 159 ``` 160 161  162 163 164## 添加事件 165 166Button组件通常用于触发某些操作,可以绑定onClick事件来响应点击操作后的自定义行为。 167 168```ts 169Button('Ok', { type: ButtonType.Normal, stateEffect: true }) 170 .onClick(()=>{ 171 console.info('Button onClick') 172 }) 173``` 174 175 176## 场景示例 177 178- 用于启动操作。 179 180 可以用按钮启动任何用户界面元素,按钮会根据用户的操作触发相应的事件。例如,在List容器里通过点击按钮进行页面跳转。 181 182 ```ts 183 // xxx.ets 184 @Entry 185 @Component 186 struct ButtonCase1 { 187 pathStack: NavPathStack = new NavPathStack(); 188 189 @Builder 190 PageMap(name: string) { 191 if (name === "first_page") { 192 pageOneTmp() 193 } else if (name === "second_page") { 194 pageTwoTmp() 195 } else if (name === "third_page") { 196 pageThreeTmp() 197 } 198 } 199 200 build() { 201 Navigation(this.pathStack) { 202 List({ space: 4 }) { 203 ListItem() { 204 Button("First").onClick(() => { 205 this.pathStack.pushPath({ name: "first_page"}) 206 }) 207 .width('100%') 208 } 209 210 ListItem() { 211 Button("Second").onClick(() => { 212 this.pathStack.pushPath({ name: "second_page"}) 213 }) 214 .width('100%') 215 } 216 217 ListItem() { 218 Button("Third").onClick(() => { 219 this.pathStack.pushPath({ name: "third_page"}) 220 }) 221 .width('100%') 222 } 223 } 224 .listDirection(Axis.Vertical) 225 .backgroundColor(0xDCDCDC).padding(20) 226 } 227 .mode(NavigationMode.Stack) 228 .navDestination(this.PageMap) 229 } 230 } 231 232 // pageOne 233 @Component 234 export struct pageOneTmp { 235 pathStack: NavPathStack = new NavPathStack(); 236 237 build() { 238 NavDestination() { 239 Column() { 240 Text("first_page") 241 }.width('100%').height('100%') 242 }.title("pageOne") 243 .onBackPressed(() => { 244 const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素 245 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 246 return true 247 }) 248 .onReady((context: NavDestinationContext) => { 249 this.pathStack = context.pathStack 250 }) 251 } 252 } 253 254 // pageTwo 255 @Component 256 export struct pageTwoTmp { 257 pathStack: NavPathStack = new NavPathStack(); 258 259 build() { 260 NavDestination() { 261 Column() { 262 Text("second_page") 263 }.width('100%').height('100%') 264 }.title("pageTwo") 265 .onBackPressed(() => { 266 const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素 267 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 268 return true 269 }) 270 .onReady((context: NavDestinationContext) => { 271 this.pathStack = context.pathStack 272 }) 273 } 274 } 275 276 // pageThree 277 @Component 278 export struct pageThreeTmp { 279 pathStack: NavPathStack = new NavPathStack(); 280 281 build() { 282 NavDestination() { 283 Column() { 284 Text("third_page") 285 }.width('100%').height('100%') 286 }.title("pageThree") 287 .onBackPressed(() => { 288 const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素 289 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 290 return true 291 }) 292 .onReady((context: NavDestinationContext) => { 293 this.pathStack = context.pathStack 294 }) 295 } 296 } 297 ``` 298 299  300 301 302- 用于提交表单。 303 304 在用户登录/注册页面,使用按钮进行登录或注册操作。 305 306 ```ts 307 // xxx.ets 308 @Entry 309 @Component 310 struct ButtonCase2 { 311 build() { 312 Column() { 313 TextInput({ placeholder: 'input your username' }).margin({ top: 20 }) 314 TextInput({ placeholder: 'input your password' }).type(InputType.Password).margin({ top: 20 }) 315 Button('Register').width(300).margin({ top: 20 }) 316 .onClick(() => { 317 // 需要执行的操作 318 }) 319 }.padding(20) 320 } 321 } 322 ``` 323 324  325 326- 悬浮按钮。 327 328 在可以滑动的界面,滑动时按钮始终保持悬浮状态。 329 330 ```ts 331 // xxx.ets 332 @Entry 333 @Component 334 struct HoverButtonExample { 335 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 336 build() { 337 Stack() { 338 List({ space: 20, initialIndex: 0 }) { 339 ForEach(this.arr, (item:number) => { 340 ListItem() { 341 Text('' + item) 342 .width('100%').height(100).fontSize(16) 343 .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF) 344 } 345 }, (item:number) => item.toString()) 346 }.width('90%') 347 Button() { 348 Image($r('app.media.ic_public_add')) 349 .width(50) 350 .height(50) 351 } 352 .width(60) 353 .height(60) 354 .position({x: '80%', y: 600}) 355 .shadow({radius: 10}) 356 .onClick(() => { 357 // 需要执行的操作 358 }) 359 } 360 .width('100%') 361 .height('100%') 362 .backgroundColor(0xDCDCDC) 363 .padding({ top: 5 }) 364 } 365 } 366 ``` 367 368  369