W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
在 Flutter 中頁面UI通常都是由一些低階別的組件組合而成,當我們需要封裝一些通用組件時,應該首先考慮是否可以通過組合其它組件來實現,如果可以,則應優(yōu)先使用組合,因為直接通過現有組件拼裝會非常簡單、靈活、高效。
Flutter Material 組件庫中的按鈕默認不支持漸變背景,為了實現漸變背景按鈕,我們自定義一個GradientButton
組件,它需要支持一下功能:
我們先來看看最終要實現的效果(圖10-1):
我們DecoratedBox
可以支持背景色漸變和圓角,InkWell
在手指按下有漣漪效果,所以我們可以通過組合DecoratedBox
和InkWell
來實現GradientButton
,代碼如下:
import 'package:flutter/material.dart';
class GradientButton extends StatelessWidget {
GradientButton({
this.colors,
this.width,
this.height,
this.onPressed,
this.borderRadius,
@required this.child,
});
// 漸變色數組
final List<Color> colors;
// 按鈕寬高
final double width;
final double height;
final Widget child;
final BorderRadius borderRadius;
//點擊回調
final GestureTapCallback onPressed;
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
//確保colors數組不空
List<Color> _colors = colors ??
[theme.primaryColor, theme.primaryColorDark ?? theme.primaryColor];
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(colors: _colors),
borderRadius: borderRadius,
),
child: Material(
type: MaterialType.transparency,
child: InkWell(
splashColor: _colors.last,
highlightColor: Colors.transparent,
borderRadius: borderRadius,
onTap: onPressed,
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(height: height, width: width),
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DefaultTextStyle(
style: TextStyle(fontWeight: FontWeight.bold),
child: child,
),
),
),
),
),
),
);
}
}
可以看到GradientButton
是由DecoratedBox
、Padding
、Center
、InkWell
等組件組合而成。當然上面的代碼只是一個示例,作為一個按鈕它還并不完整,比如沒有禁用狀態(tài),讀者可以根據實際需要來完善。
import 'package:flutter/material.dart';
import '../widgets/index.dart';
class GradientButtonRoute extends StatefulWidget {
@override
_GradientButtonRouteState createState() => _GradientButtonRouteState();
}
class _GradientButtonRouteState extends State<GradientButtonRoute> {
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
GradientButton(
colors: [Colors.orange, Colors.red],
height: 50.0,
child: Text("Submit"),
onPressed: onTap,
),
GradientButton(
height: 50.0,
colors: [Colors.lightGreen, Colors.green[700]],
child: Text("Submit"),
onPressed: onTap,
),
GradientButton(
height: 50.0,
colors: [Colors.lightBlue[300], Colors.blueAccent],
child: Text("Submit"),
onPressed: onTap,
),
],
),
);
}
onTap() {
print("button click");
}
}
通過組合的方式定義組件和我們之前寫界面并無差異,不過在抽離出單獨的組件時我們要考慮代碼規(guī)范性,如必要參數要用@required
標注,對于可選參數在特定場景需要判空或設置默認值等。這是由于使用者大多時候可能不了解組件的內部細節(jié),所以為了保證代碼健壯性,我們需要在用戶錯誤地使用組件時能夠兼容或報錯提示(使用assert
斷言函數)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯系方式:
更多建議: