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 ```ts 101 Button('Disable', { type: ButtonType.ROUNDED_RECTANGLE, stateEffect: true }) 102 .backgroundColor(0x317aff) 103 .width(90) 104 .height(40) 105 ``` 106 107  108 109## 自定义样式 110 111- 设置边框弧度。 112 113 使用通用属性来自定义按钮样式。例如通过borderRadius属性设置按钮的边框弧度。 114 115 ```ts 116 Button('circle border', { type: ButtonType.Normal }) 117 .borderRadius(20) 118 .height(40) 119 ``` 120 121  122 123 124- 设置文本样式。 125 126 通过添加文本样式设置按钮文本的展示样式。 127 128 ```ts 129 Button('font style', { type: ButtonType.Normal }) 130 .fontSize(20) 131 .fontColor(Color.Pink) 132 .fontWeight(800) 133 ``` 134 135  136 137 138- 设置背景颜色。 139 140 添加backgroundColor属性设置按钮的背景颜色。 141 142 ```ts 143 Button('background color').backgroundColor(0xF55A42) 144 ``` 145 146  147 148 149- 创建功能型按钮。 150 151 为删除操作创建一个按钮。 152 153 ```ts 154 let MarLeft: Record<string, number> = { 'left': 20 } 155 Button({ type: ButtonType.Circle, stateEffect: true }) { 156 Image($r('app.media.ic_public_delete_filled')).width(30).height(30) 157 }.width(55).height(55).margin(MarLeft).backgroundColor(0xF55A42) 158 ``` 159 160  161 162 163## 添加事件 164 165Button组件通常用于触发某些操作,可以绑定onClick事件来响应点击操作后的自定义行为。 166 167```ts 168Button('Ok', { type: ButtonType.Normal, stateEffect: true }) 169 .onClick(()=>{ 170 console.info('Button onClick') 171 }) 172``` 173 174 175## 场景示例 176 177- 用于启动操作。 178 179 可以用按钮启动任何用户界面元素,按钮会根据用户的操作触发相应的事件。例如,在List容器里通过点击按钮进行页面跳转。 180 181 ```ts 182 // xxx.ets 183 @Entry 184 @Component 185 struct ButtonCase1 { 186 pathStack: NavPathStack = new NavPathStack(); 187 188 @Builder 189 PageMap(name: string) { 190 if (name === "first_page") { 191 pageOneTmp() 192 } else if (name === "second_page") { 193 pageTwoTmp() 194 } else if (name === "third_page") { 195 pageThreeTmp() 196 } 197 } 198 199 build() { 200 Navigation(this.pathStack) { 201 List({ space: 4 }) { 202 ListItem() { 203 Button("First").onClick(() => { 204 this.pathStack.pushPath({ name: "first_page"}) 205 }) 206 .width('100%') 207 } 208 209 ListItem() { 210 Button("Second").onClick(() => { 211 this.pathStack.pushPath({ name: "second_page"}) 212 }) 213 .width('100%') 214 } 215 216 ListItem() { 217 Button("Third").onClick(() => { 218 this.pathStack.pushPath({ name: "third_page"}) 219 }) 220 .width('100%') 221 } 222 } 223 .listDirection(Axis.Vertical) 224 .backgroundColor(0xDCDCDC).padding(20) 225 } 226 .mode(NavigationMode.Stack) 227 .navDestination(this.PageMap) 228 } 229 } 230 231 // pageOne 232 @Component 233 export struct pageOneTmp { 234 pathStack: NavPathStack = new NavPathStack(); 235 236 build() { 237 NavDestination() { 238 Column() { 239 Text("first_page") 240 }.width('100%').height('100%') 241 }.title("pageOne") 242 .onBackPressed(() => { 243 const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素 244 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 245 return true 246 }) 247 .onReady((context: NavDestinationContext) => { 248 this.pathStack = context.pathStack 249 }) 250 } 251 } 252 253 // pageTwo 254 @Component 255 export struct pageTwoTmp { 256 pathStack: NavPathStack = new NavPathStack(); 257 258 build() { 259 NavDestination() { 260 Column() { 261 Text("second_page") 262 }.width('100%').height('100%') 263 }.title("pageTwo") 264 .onBackPressed(() => { 265 const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素 266 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 267 return true 268 }) 269 .onReady((context: NavDestinationContext) => { 270 this.pathStack = context.pathStack 271 }) 272 } 273 } 274 275 // pageThree 276 @Component 277 export struct pageThreeTmp { 278 pathStack: NavPathStack = new NavPathStack(); 279 280 build() { 281 NavDestination() { 282 Column() { 283 Text("third_page") 284 }.width('100%').height('100%') 285 }.title("pageThree") 286 .onBackPressed(() => { 287 const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素 288 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 289 return true 290 }) 291 .onReady((context: NavDestinationContext) => { 292 this.pathStack = context.pathStack 293 }) 294 } 295 } 296 ``` 297 298  299 300 301- 用于提交表单。 302 303 在用户登录/注册页面,使用按钮进行登录或注册操作。 304 305 ```ts 306 // xxx.ets 307 @Entry 308 @Component 309 struct ButtonCase2 { 310 build() { 311 Column() { 312 TextInput({ placeholder: 'input your username' }).margin({ top: 20 }) 313 TextInput({ placeholder: 'input your password' }).type(InputType.Password).margin({ top: 20 }) 314 Button('Register').width(300).margin({ top: 20 }) 315 .onClick(() => { 316 // 需要执行的操作 317 }) 318 }.padding(20) 319 } 320 } 321 ``` 322 323  324 325- 悬浮按钮。 326 327 在可以滑动的界面,滑动时按钮始终保持悬浮状态。 328 329 ```ts 330 // xxx.ets 331 @Entry 332 @Component 333 struct HoverButtonExample { 334 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 335 build() { 336 Stack() { 337 List({ space: 20, initialIndex: 0 }) { 338 ForEach(this.arr, (item:number) => { 339 ListItem() { 340 Text('' + item) 341 .width('100%').height(100).fontSize(16) 342 .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF) 343 } 344 }, (item:number) => item.toString()) 345 }.width('90%') 346 Button() { 347 Image($r('app.media.ic_public_add')) 348 .width(50) 349 .height(50) 350 } 351 .width(60) 352 .height(60) 353 .position({x: '80%', y: 600}) 354 .shadow({radius: 10}) 355 .onClick(() => { 356 // 需要执行的操作 357 }) 358 } 359 .width('100%') 360 .height('100%') 361 .backgroundColor(0xDCDCDC) 362 .padding({ top: 5 }) 363 } 364 } 365 ``` 366 367  368