W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在 Flutter 中頁(yè)面UI通常都是由一些低階別的組件組合而成,當(dāng)我們需要封裝一些通用組件時(shí),應(yīng)該首先考慮是否可以通過組合其它組件來(lái)實(shí)現(xiàn),如果可以,則應(yīng)優(yōu)先使用組合,因?yàn)橹苯油ㄟ^現(xiàn)有組件拼裝會(huì)非常簡(jiǎn)單、靈活、高效。
Flutter Material 組件庫(kù)中的按鈕默認(rèn)不支持漸變背景,為了實(shí)現(xiàn)漸變背景按鈕,我們自定義一個(gè)GradientButton
組件,它需要支持一下功能:
我們先來(lái)看看最終要實(shí)現(xiàn)的效果(圖10-1):
我們DecoratedBox
可以支持背景色漸變和圓角,InkWell
在手指按下有漣漪效果,所以我們可以通過組合DecoratedBox
和InkWell
來(lái)實(shí)現(xiàn)GradientButton
,代碼如下:
import 'package:flutter/material.dart';
class GradientButton extends StatelessWidget {
GradientButton({
this.colors,
this.width,
this.height,
this.onPressed,
this.borderRadius,
@required this.child,
});
// 漸變色數(shù)組
final List<Color> colors;
// 按鈕寬高
final double width;
final double height;
final Widget child;
final BorderRadius borderRadius;
//點(diǎn)擊回調(diào)
final GestureTapCallback onPressed;
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
//確保colors數(shù)組不空
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
等組件組合而成。當(dāng)然上面的代碼只是一個(gè)示例,作為一個(gè)按鈕它還并不完整,比如沒有禁用狀態(tài),讀者可以根據(jù)實(shí)際需要來(lá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");
}
}
通過組合的方式定義組件和我們之前寫界面并無(wú)差異,不過在抽離出單獨(dú)的組件時(shí)我們要考慮代碼規(guī)范性,如必要參數(shù)要用@required
標(biāo)注,對(duì)于可選參數(shù)在特定場(chǎng)景需要判空或設(shè)置默認(rèn)值等。這是由于使用者大多時(shí)候可能不了解組件的內(nèi)部細(xì)節(jié),所以為了保證代碼健壯性,我們需要在用戶錯(cuò)誤地使用組件時(shí)能夠兼容或報(bào)錯(cuò)提示(使用assert
斷言函數(shù))。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: