ex_widget.dart 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. import 'package:flutter/gestures.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/semantics.dart';
  4. import 'package:shared/utils/ext_dart.dart';
  5. /// 手势 tap
  6. typedef GestureOnTapChangeCallback = void Function<T>(T val);
  7. //点击防抖类型
  8. enum ClickType { none, throttle, debounce }
  9. /// 扩展 Widget
  10. extension ExWidget on Widget {
  11. /// 对齐
  12. Widget align(
  13. AlignmentGeometry alignment, {
  14. Key? key,
  15. }) =>
  16. Align(
  17. key: key,
  18. alignment: alignment,
  19. child: this,
  20. );
  21. /// 对齐 中间
  22. Widget alignCenter() => align(Alignment.center);
  23. /// 对齐 左边
  24. Widget alignLeft() => align(Alignment.centerLeft);
  25. /// 对齐 右边
  26. Widget alignRight() => align(Alignment.centerRight);
  27. /// 对齐 顶部
  28. Widget alignTop() => align(Alignment.topCenter);
  29. /// 对齐 底部
  30. Widget alignBottom() => align(Alignment.bottomCenter);
  31. // 比例布局
  32. Widget aspectRatio({
  33. Key? key,
  34. required double aspectRatio,
  35. }) =>
  36. AspectRatio(
  37. key: key,
  38. aspectRatio: aspectRatio,
  39. child: this,
  40. );
  41. /// 背景颜色
  42. Widget backgroundColor(
  43. Color? color, {
  44. Key? key,
  45. }) =>
  46. DecoratedBox(
  47. key: key,
  48. child: this,
  49. decoration: BoxDecoration(color: color),
  50. );
  51. /// 背景图片
  52. Widget backgroundImage(
  53. DecorationImage image, {
  54. Key? key,
  55. }) =>
  56. DecoratedBox(
  57. key: key,
  58. child: this,
  59. decoration: BoxDecoration(image: image),
  60. );
  61. /// 边框
  62. Widget border({
  63. Key? key,
  64. double? all,
  65. double? left,
  66. double? right,
  67. double? top,
  68. double? bottom,
  69. Color color = const Color(0xFF000000),
  70. BorderStyle style = BorderStyle.solid,
  71. }) {
  72. BoxDecoration decoration = BoxDecoration(
  73. border: Border(
  74. left: (left ?? all) == null ? BorderSide.none : BorderSide(color: color, width: left ?? all ?? 0, style: style),
  75. right: (right ?? all) == null ? BorderSide.none : BorderSide(color: color, width: right ?? all ?? 0, style: style),
  76. top: (top ?? all) == null ? BorderSide.none : BorderSide(color: color, width: top ?? all ?? 0, style: style),
  77. bottom: (bottom ?? all) == null ? BorderSide.none : BorderSide(color: color, width: bottom ?? all ?? 0, style: style),
  78. ),
  79. );
  80. return DecoratedBox(
  81. key: key,
  82. child: this,
  83. decoration: decoration,
  84. );
  85. }
  86. /// 圆角
  87. Widget borderRadius({
  88. Key? key,
  89. double? all,
  90. double? topLeft,
  91. double? topRight,
  92. double? bottomLeft,
  93. double? bottomRight,
  94. }) {
  95. BoxDecoration decoration = BoxDecoration(
  96. borderRadius: BorderRadius.only(
  97. topLeft: Radius.circular(topLeft ?? all ?? 0.0),
  98. topRight: Radius.circular(topRight ?? all ?? 0.0),
  99. bottomLeft: Radius.circular(bottomLeft ?? all ?? 0.0),
  100. bottomRight: Radius.circular(bottomRight ?? all ?? 0.0),
  101. ),
  102. );
  103. return DecoratedBox(
  104. key: key,
  105. child: this,
  106. decoration: decoration,
  107. );
  108. }
  109. /// 阴影
  110. Widget boxShadow({
  111. Key? key,
  112. Color color = const Color(0xFF000000),
  113. Offset offset = Offset.zero,
  114. double blurRadius = 0.0,
  115. double spreadRadius = 0.0,
  116. }) {
  117. BoxDecoration decoration = BoxDecoration(
  118. boxShadow: [
  119. BoxShadow(
  120. color: color,
  121. blurRadius: blurRadius,
  122. spreadRadius: spreadRadius,
  123. offset: offset,
  124. ),
  125. ],
  126. );
  127. return DecoratedBox(
  128. key: key,
  129. child: this,
  130. decoration: decoration,
  131. );
  132. }
  133. /// 卡片
  134. Widget card({
  135. Key? key,
  136. Color? color,
  137. double? elevation,
  138. ShapeBorder? shape,
  139. bool borderOnForeground = true,
  140. EdgeInsetsGeometry? margin,
  141. Clip? clipBehavior,
  142. bool semanticContainer = true,
  143. }) =>
  144. Card(
  145. key: key,
  146. color: color,
  147. elevation: elevation,
  148. shape: shape,
  149. borderOnForeground: borderOnForeground,
  150. margin: margin,
  151. clipBehavior: clipBehavior,
  152. semanticContainer: semanticContainer,
  153. child: this,
  154. );
  155. // 居中
  156. Widget center({
  157. Key? key,
  158. double? widthFactor,
  159. double? heightFactor,
  160. }) =>
  161. Center(
  162. key: key,
  163. widthFactor: widthFactor,
  164. heightFactor: heightFactor,
  165. child: this,
  166. );
  167. /// 裁剪 oval
  168. Widget clipOval({Key? key}) => ClipOval(
  169. key: key,
  170. child: this,
  171. );
  172. /// 裁剪 rect
  173. Widget clipRect({
  174. Key? key,
  175. CustomClipper<Rect>? clipper,
  176. Clip clipBehavior = Clip.hardEdge,
  177. }) =>
  178. ClipRect(
  179. key: key,
  180. clipper: clipper,
  181. clipBehavior: clipBehavior,
  182. child: this,
  183. );
  184. /// 裁剪圆角
  185. Widget clipRRect({
  186. Key? key,
  187. double? all,
  188. double? topLeft,
  189. double? topRight,
  190. double? bottomLeft,
  191. double? bottomRight,
  192. CustomClipper<RRect>? clipper,
  193. Clip clipBehavior = Clip.antiAlias,
  194. }) =>
  195. ClipRRect(
  196. key: key,
  197. child: this,
  198. clipper: clipper,
  199. clipBehavior: clipBehavior,
  200. borderRadius: BorderRadius.only(
  201. topLeft: Radius.circular(topLeft ?? all ?? 0.0),
  202. topRight: Radius.circular(topRight ?? all ?? 0.0),
  203. bottomLeft: Radius.circular(bottomLeft ?? all ?? 0.0),
  204. bottomRight: Radius.circular(bottomRight ?? all ?? 0.0),
  205. ),
  206. );
  207. /// 约束
  208. Widget constrained({
  209. Key? key,
  210. double? width,
  211. double? height,
  212. double minWidth = 0.0,
  213. double maxWidth = double.infinity,
  214. double minHeight = 0.0,
  215. double maxHeight = double.infinity,
  216. }) {
  217. BoxConstraints constraints = BoxConstraints(
  218. minWidth: minWidth,
  219. maxWidth: maxWidth,
  220. minHeight: minHeight,
  221. maxHeight: maxHeight,
  222. );
  223. constraints = (width != null || height != null) ? constraints.tighten(width: width, height: height) : constraints;
  224. return ConstrainedBox(
  225. key: key,
  226. child: this,
  227. constraints: constraints,
  228. );
  229. }
  230. /// 盒子装饰器
  231. Widget decorated({
  232. Key? key,
  233. Color? color,
  234. DecorationImage? image,
  235. BoxBorder? border,
  236. BorderRadius? borderRadius,
  237. List<BoxShadow>? boxShadow,
  238. Gradient? gradient,
  239. BlendMode? backgroundBlendMode,
  240. BoxShape shape = BoxShape.rectangle,
  241. DecorationPosition position = DecorationPosition.background,
  242. }) {
  243. BoxDecoration decoration = BoxDecoration(
  244. color: color,
  245. image: image,
  246. border: border,
  247. borderRadius: borderRadius,
  248. boxShadow: boxShadow,
  249. gradient: gradient,
  250. backgroundBlendMode: backgroundBlendMode,
  251. shape: shape,
  252. );
  253. return DecoratedBox(
  254. key: key,
  255. child: this,
  256. decoration: decoration,
  257. position: position,
  258. );
  259. }
  260. /// elevation
  261. Widget elevation(
  262. double elevation, {
  263. Key? key,
  264. BorderRadiusGeometry borderRadius = BorderRadius.zero,
  265. Color shadowColor = const Color(0xFF000000),
  266. }) =>
  267. Material(
  268. key: key,
  269. child: this,
  270. color: Colors.transparent,
  271. elevation: elevation,
  272. borderRadius: borderRadius,
  273. shadowColor: shadowColor,
  274. );
  275. /// expanded 撑满,用于线性布局
  276. Widget expanded({
  277. Key? key,
  278. int flex = 1,
  279. }) =>
  280. Expanded(
  281. key: key,
  282. child: this,
  283. flex: flex,
  284. );
  285. /// 调整子控件大小与位置
  286. Widget fittedBox({
  287. Key? key,
  288. BoxFit fit = BoxFit.contain,
  289. AlignmentGeometry alignment = Alignment.center,
  290. }) =>
  291. FittedBox(
  292. key: key,
  293. fit: fit,
  294. alignment: alignment,
  295. child: this,
  296. );
  297. /// 弹性布局 flexible,用于线性布局
  298. Widget flexible({
  299. Key? key,
  300. int flex = 1,
  301. FlexFit fit = FlexFit.loose,
  302. }) =>
  303. Flexible(
  304. key: key,
  305. child: this,
  306. flex: flex,
  307. fit: fit,
  308. );
  309. Widget fractionallySizedBox({
  310. Key? key,
  311. AlignmentGeometry alignment = Alignment.center,
  312. double? widthFactor,
  313. double? heightFactor,
  314. }) =>
  315. FractionallySizedBox(
  316. key: key,
  317. alignment: alignment,
  318. widthFactor: widthFactor,
  319. heightFactor: heightFactor,
  320. child: this,
  321. );
  322. /// 手势
  323. Widget gestures({
  324. Key? key,
  325. GestureOnTapChangeCallback? onTapChange,
  326. GestureTapDownCallback? onTapDown,
  327. GestureTapUpCallback? onTapUp,
  328. GestureTapCallback? onTap,
  329. GestureTapCancelCallback? onTapCancel,
  330. GestureTapDownCallback? onSecondaryTapDown,
  331. GestureTapUpCallback? onSecondaryTapUp,
  332. GestureTapCancelCallback? onSecondaryTapCancel,
  333. GestureTapCallback? onDoubleTap,
  334. GestureLongPressCallback? onLongPress,
  335. GestureLongPressStartCallback? onLongPressStart,
  336. GestureLongPressMoveUpdateCallback? onLongPressMoveUpdate,
  337. GestureLongPressUpCallback? onLongPressUp,
  338. GestureLongPressEndCallback? onLongPressEnd,
  339. GestureDragDownCallback? onVerticalDragDown,
  340. GestureDragStartCallback? onVerticalDragStart,
  341. GestureDragUpdateCallback? onVerticalDragUpdate,
  342. GestureDragEndCallback? onVerticalDragEnd,
  343. GestureDragCancelCallback? onVerticalDragCancel,
  344. GestureDragDownCallback? onHorizontalDragDown,
  345. GestureDragStartCallback? onHorizontalDragStart,
  346. GestureDragUpdateCallback? onHorizontalDragUpdate,
  347. GestureDragEndCallback? onHorizontalDragEnd,
  348. GestureDragCancelCallback? onHorizontalDragCancel,
  349. GestureDragDownCallback? onPanDown,
  350. GestureDragStartCallback? onPanStart,
  351. GestureDragUpdateCallback? onPanUpdate,
  352. GestureDragEndCallback? onPanEnd,
  353. GestureDragCancelCallback? onPanCancel,
  354. GestureScaleStartCallback? onScaleStart,
  355. GestureScaleUpdateCallback? onScaleUpdate,
  356. GestureScaleEndCallback? onScaleEnd,
  357. GestureForcePressStartCallback? onForcePressStart,
  358. GestureForcePressPeakCallback? onForcePressPeak,
  359. GestureForcePressUpdateCallback? onForcePressUpdate,
  360. GestureForcePressEndCallback? onForcePressEnd,
  361. HitTestBehavior? behavior,
  362. bool excludeFromSemantics = false,
  363. DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  364. }) =>
  365. GestureDetector(
  366. key: key,
  367. onTapDown: (TapDownDetails tapDownDetails) {
  368. if (onTapDown != null) onTapDown(tapDownDetails);
  369. if (onTapChange != null) onTapChange(true);
  370. },
  371. onTapCancel: () {
  372. if (onTapCancel != null) onTapCancel();
  373. if (onTapChange != null) onTapChange(false);
  374. },
  375. onTap: () {
  376. if (onTap != null) onTap();
  377. if (onTapChange != null) onTapChange(false);
  378. },
  379. onTapUp: onTapUp,
  380. onDoubleTap: onDoubleTap,
  381. onLongPress: onLongPress,
  382. onLongPressStart: onLongPressStart,
  383. onLongPressEnd: onLongPressEnd,
  384. onLongPressMoveUpdate: onLongPressMoveUpdate,
  385. onLongPressUp: onLongPressUp,
  386. onVerticalDragStart: onVerticalDragStart,
  387. onVerticalDragEnd: onVerticalDragEnd,
  388. onVerticalDragDown: onVerticalDragDown,
  389. onVerticalDragCancel: onVerticalDragCancel,
  390. onVerticalDragUpdate: onVerticalDragUpdate,
  391. onHorizontalDragStart: onHorizontalDragStart,
  392. onHorizontalDragEnd: onHorizontalDragEnd,
  393. onHorizontalDragCancel: onHorizontalDragCancel,
  394. onHorizontalDragUpdate: onHorizontalDragUpdate,
  395. onHorizontalDragDown: onHorizontalDragDown,
  396. onForcePressStart: onForcePressStart,
  397. onForcePressEnd: onForcePressEnd,
  398. onForcePressPeak: onForcePressPeak,
  399. onForcePressUpdate: onForcePressUpdate,
  400. onPanStart: onPanStart,
  401. onPanEnd: onPanEnd,
  402. onPanCancel: onPanCancel,
  403. onPanDown: onPanDown,
  404. onPanUpdate: onPanUpdate,
  405. onScaleStart: onScaleStart,
  406. onScaleEnd: onScaleEnd,
  407. onScaleUpdate: onScaleUpdate,
  408. behavior: behavior ?? HitTestBehavior.opaque,
  409. excludeFromSemantics: excludeFromSemantics,
  410. dragStartBehavior: dragStartBehavior,
  411. child: this,
  412. );
  413. /// 手势
  414. Widget onTap(
  415. GestureTapCallback onTap, {
  416. Key? key,
  417. HitTestBehavior? behavior,
  418. ClickType type = ClickType.none, //默认没有点击类型
  419. int milliseconds = 500, //点击类型的时间戳(毫秒)
  420. bool excludeFromSemantics = false,
  421. DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  422. }) =>
  423. GestureDetector(
  424. key: key,
  425. onTap: type == ClickType.debounce
  426. ? onTap.debounce(milliseconds)
  427. : type == ClickType.throttle
  428. ? onTap.throttle(milliseconds)
  429. : onTap,
  430. behavior: behavior ?? HitTestBehavior.opaque,
  431. excludeFromSemantics: excludeFromSemantics,
  432. dragStartBehavior: dragStartBehavior,
  433. child: this,
  434. );
  435. /// 长按手势
  436. Widget onLongPress(
  437. GestureTapCallback onLongPress, {
  438. Key? key,
  439. HitTestBehavior? behavior,
  440. bool excludeFromSemantics = false,
  441. DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  442. }) =>
  443. GestureDetector(
  444. key: key,
  445. onLongPress: onLongPress,
  446. behavior: behavior ?? HitTestBehavior.opaque,
  447. excludeFromSemantics: excludeFromSemantics,
  448. dragStartBehavior: dragStartBehavior,
  449. child: this,
  450. );
  451. /// 约束 高度
  452. Widget height(
  453. double height, {
  454. Key? key,
  455. }) =>
  456. ConstrainedBox(
  457. key: key,
  458. child: this,
  459. constraints: BoxConstraints.tightFor(height: height),
  460. );
  461. /// 限制盒子 最大宽高
  462. Widget limitedBox({
  463. Key? key,
  464. double maxWidth = double.infinity,
  465. double maxHeight = double.infinity,
  466. }) =>
  467. LimitedBox(
  468. key: key,
  469. maxWidth: maxWidth,
  470. maxHeight: maxHeight,
  471. child: this,
  472. );
  473. /// 偏移
  474. Widget offstage({
  475. Key? key,
  476. bool offstage = true,
  477. }) =>
  478. Offstage(
  479. key: key,
  480. offstage: offstage,
  481. child: this,
  482. );
  483. /// 透明度
  484. Widget opacity(
  485. double opacity, {
  486. Key? key,
  487. bool alwaysIncludeSemantics = false,
  488. }) =>
  489. Opacity(
  490. key: key,
  491. opacity: opacity,
  492. alwaysIncludeSemantics: alwaysIncludeSemantics,
  493. child: this,
  494. );
  495. /// 溢出
  496. Widget overflow({
  497. Key? key,
  498. AlignmentGeometry alignment = Alignment.center,
  499. double? minWidth,
  500. double? maxWidth,
  501. double? minHeight,
  502. double? maxHeight,
  503. }) =>
  504. OverflowBox(
  505. key: key,
  506. alignment: alignment,
  507. minWidth: minWidth,
  508. maxWidth: minWidth,
  509. minHeight: minHeight,
  510. maxHeight: maxHeight,
  511. child: this,
  512. );
  513. /// 内间距
  514. Widget padding({
  515. Key? key,
  516. EdgeInsetsGeometry? value,
  517. double? all,
  518. double? horizontal,
  519. double? vertical,
  520. double? top,
  521. double? bottom,
  522. double? left,
  523. double? right,
  524. }) =>
  525. Padding(
  526. key: key,
  527. padding: value ??
  528. EdgeInsets.only(
  529. top: top ?? vertical ?? all ?? 0.0,
  530. bottom: bottom ?? vertical ?? all ?? 0.0,
  531. left: left ?? horizontal ?? all ?? 0.0,
  532. right: right ?? horizontal ?? all ?? 0.0,
  533. ),
  534. child: this,
  535. );
  536. /// 内间距 下
  537. Widget paddingBottom(double val) => padding(bottom: val);
  538. /// 内间距 横向
  539. Widget paddingHorizontal(double val) => padding(horizontal: val);
  540. /// 内间距 左
  541. Widget paddingLeft(double val) => padding(left: val);
  542. /// 内间距 右
  543. Widget paddingRight(double val) => padding(right: val);
  544. /// 内间距 上
  545. Widget paddingTop(double val) => padding(top: val);
  546. /// 内间距 纵向
  547. Widget paddingVertical(double val) => padding(vertical: val);
  548. /// stack布局 位置
  549. Widget positioned({
  550. Key? key,
  551. double? left,
  552. double? top,
  553. double? right,
  554. double? bottom,
  555. double? width,
  556. double? height,
  557. }) =>
  558. Positioned(
  559. key: key,
  560. child: this,
  561. left: left,
  562. top: top,
  563. right: right,
  564. bottom: bottom,
  565. width: width,
  566. height: height,
  567. );
  568. /// 涟漪
  569. Widget ripple({
  570. Key? key,
  571. Color? bgColor,
  572. Color? focusColor,
  573. Color? hoverColor,
  574. Color? highlightColor,
  575. Color? splashColor,
  576. InteractiveInkFeatureFactory? splashFactory,
  577. double? radius,
  578. ShapeBorder? customBorder,
  579. bool enableFeedback = true,
  580. bool excludeFromSemantics = false,
  581. FocusNode? focusNode,
  582. bool canRequestFocus = true,
  583. bool autoFocus = false,
  584. bool enable = true,
  585. }) =>
  586. enable
  587. ? Builder(
  588. key: key,
  589. builder: (BuildContext context) {
  590. GestureDetector? gestures = context.findAncestorWidgetOfExactType<GestureDetector>();
  591. return Material(
  592. color: bgColor ?? Colors.transparent,
  593. child: InkWell(
  594. focusColor: focusColor,
  595. hoverColor: hoverColor,
  596. highlightColor: highlightColor,
  597. splashColor: splashColor,
  598. splashFactory: splashFactory,
  599. radius: radius,
  600. customBorder: customBorder,
  601. enableFeedback: enableFeedback,
  602. excludeFromSemantics: excludeFromSemantics,
  603. focusNode: focusNode,
  604. canRequestFocus: canRequestFocus,
  605. autofocus: autoFocus,
  606. onTap: gestures?.onTap,
  607. child: this,
  608. ),
  609. );
  610. },
  611. )
  612. : Builder(
  613. key: key,
  614. builder: (context) => this,
  615. );
  616. // 刘海屏 特殊屏幕 留白
  617. Widget safeArea({
  618. Key? key,
  619. bool top = true,
  620. bool bottom = true,
  621. bool left = true,
  622. bool right = true,
  623. }) =>
  624. SafeArea(
  625. key: key,
  626. top: top,
  627. bottom: bottom,
  628. left: left,
  629. right: right,
  630. child: this,
  631. );
  632. /// 比例缩放
  633. Widget scale({
  634. Key? key,
  635. double? all,
  636. double? x,
  637. double? y,
  638. Offset? origin,
  639. AlignmentGeometry alignment = Alignment.center,
  640. bool transformHitTests = true,
  641. }) =>
  642. Transform(
  643. key: key,
  644. transform: Matrix4.diagonal3Values(x ?? all ?? 0, y ?? all ?? 0, 1.0),
  645. alignment: alignment,
  646. child: this,
  647. origin: origin,
  648. transformHitTests: transformHitTests,
  649. );
  650. /// 滚动视图
  651. Widget scrollable({
  652. Key? key,
  653. Axis scrollDirection = Axis.vertical,
  654. bool reverse = false,
  655. bool? primary,
  656. ScrollPhysics? physics,
  657. ScrollController? controller,
  658. DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  659. EdgeInsetsGeometry? padding,
  660. }) =>
  661. SingleChildScrollView(
  662. key: key,
  663. child: this,
  664. scrollDirection: scrollDirection,
  665. reverse: reverse,
  666. primary: primary,
  667. physics: physics,
  668. controller: controller,
  669. dragStartBehavior: dragStartBehavior,
  670. padding: padding,
  671. );
  672. /// 语义调试
  673. /// MaterialApp.showSemanticsDebugger: true,
  674. Widget semanticsLabel(
  675. String label, {
  676. Key? key,
  677. }) =>
  678. Semantics.fromProperties(
  679. key: key,
  680. properties: SemanticsProperties(label: label),
  681. child: this,
  682. );
  683. /// 约束 宽高
  684. Widget tight({
  685. double? width,
  686. double? height,
  687. Key? key,
  688. }) =>
  689. ConstrainedBox(
  690. key: key,
  691. child: this,
  692. constraints: BoxConstraints.tightFor(width: width, height: height),
  693. );
  694. /// transforms Matrix4
  695. Widget transform({
  696. Key? key,
  697. required Matrix4 transform,
  698. Offset? origin,
  699. AlignmentGeometry? alignment,
  700. bool transformHitTests = true,
  701. }) =>
  702. Transform(
  703. key: key,
  704. transform: transform,
  705. alignment: alignment,
  706. origin: origin,
  707. transformHitTests: transformHitTests,
  708. child: this,
  709. );
  710. /// translate 变化位置
  711. Widget translate({
  712. Key? key,
  713. required Offset offset,
  714. bool transformHitTests = true,
  715. }) =>
  716. Transform.translate(
  717. key: key,
  718. offset: offset,
  719. transformHitTests: transformHitTests,
  720. child: this,
  721. );
  722. /// 约束 宽度
  723. Widget width(
  724. double width, {
  725. Key? key,
  726. }) =>
  727. ConstrainedBox(
  728. key: key,
  729. child: this,
  730. constraints: BoxConstraints.tightFor(width: width),
  731. );
  732. }