Flutter不常用元件(五)
阿新 • • 發佈:2022-12-05
PhysicalModel
為子元件設定陰影
它有以下幾個屬性:
-
Key? key
:標識鍵 -
BoxShape shape
:形狀。預設為BoxShape.rectangle -
Clip clipBehavior
:多餘部分裁剪效果。預設為Clip.none -
BorderRadius? borderRadius
:圓角 -
double elevation
:相對於放置此物理物件的父級的 z 座標。預設為0.0 -
Color color
:顏色 -
Color shadowColor
:陰影顏色。預設為Color(0xFF000000) -
Widget? child
:子元件
Center( child: PhysicalModel( shape: BoxShape.rectangle, clipBehavior: Clip.none, borderRadius: BorderRadius.all(Radius.circular(12)), color: Colors.white, elevation: 4.0, shadowColor: Color(0xFF000000), child: SizedBox(width: 200, height: 200), ), )
PhysicalShape
建立具有任意形狀剪輯的元件
它有以下幾個屬性:
-
Key? key
:標識鍵 -
CustomClipper clipper
:裁剪形狀。可以通過繼承CustomClipper自定義 -
Clip clipBehavior
:多餘部分裁剪效果。預設為Clip.none -
double elevation
:相對於放置此物理物件的父級的 z 座標。預設為0.0 -
Color color
:顏色 -
Color shadowColor
:陰影顏色。預設為Color(0xFF000000) -
Widget? child
:子元件
Center( child: PhysicalShape( elevation: 5.0, clipper: ShapeBorderClipper( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(100.0), ), ), color: Colors.orange, child: Container( height: 200.0, width: 200.0, alignment: Alignment.center, child: const Text( 'Hello, World!', style: TextStyle(color: Colors.white, fontSize: 20.0), ), ), ), )
PlatformAdaptiveIcons
使用Icons.adaptive
開頭的圖示,可以在 Android 和 IOS 兩個平臺顯示不同的圖示樣式。
RotatedBox
旋轉子元件。旋轉角度有限
它有以下幾個屬性:
-
Key? key
:標識鍵 -
int quarterTurns
:旋轉角度。1代表90°,以此類推 -
Widget? child
:子元件
Center(
child: RotatedBox(
quarterTurns: 1,
child: FlutterLogo(size: 200),
),
)
SearchDelegate
定義搜尋頁面
我們先製作一個前往搜尋頁面的元件:
Center(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
child: TextField(
readOnly: true,
decoration: const InputDecoration(
hintText: '搜尋',
suffixIcon: Icon(Icons.search),
),
onTap: () {}, // TODO
),
),
)
SearchDelegate不能直接使用,我們需要自定義一類來繼承它。
class SearchPage extends SearchDelegate<String> {
@override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
onPressed: () {
query = '';
},
icon: const Icon(Icons.clear),
),
];
}
@override
Widget? buildLeading(BuildContext context) {
return const BackButton();
}
@override
Widget buildResults(BuildContext context) {
return searchContent();
}
@override
Widget buildSuggestions(BuildContext context) {
return searchContent();
}
Widget searchContent() {
List<String> filterName = names
.where((name) => name.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemCount: filterName.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(filterName[index]),
onTap: () {
query = filterName[index];
},
);
},
);
}
}
接下來我們需要呼叫showSearch
這個方法來顯示這個介面:
onTap: () {
showSearch(context: context, delegate: SearchPage());
}
ShaderMask
建立一個將Shader生成的蒙版應用到其子級的小部件
它有以下幾個屬性:
-
Key? key
:標識鍵 -
Shader Function(Rect) shaderCallback
:呼叫以建立生成遮罩的dart:ui.Shader -
BlendMode blendMode
:平鋪模式。預設值為BlendMode.modulate -
Widget? child
:子元件
ShaderMask(
shaderCallback: (bounds) => const RadialGradient(
center: Alignment.topLeft,
radius: 1.0,
colors: [Colors.yellow, Colors.deepOrange],
tileMode: TileMode.mirror,
).createShader(bounds),
child: const Text(
"Hello World",
style: TextStyle(
fontSize: 40,
color: Colors.white, // 一定要設定為白色
fontWeight: FontWeight.bold,
),
),
)
SizedOverflowBox
關於該元件的詳細介紹可以檢視文章:SizedOverflowBox
Stepper
步驟元件
它有以下幾個元件:
-
Key? key
:標識鍵 -
List steps
:Step列表 -
ScrollPhysics? physics
:物理滾動效果 -
StepperType type
:步驟指示條顯示的方式。預設為StepperType.vertical -
int currentStep
:當前步驟。預設為0 -
void Function(int)? onStepTapped
:步驟點選事件 -
void Function()? onStepContinue
:步驟繼續事件 -
void Function()? onStepCancel
:步驟取消事件 -
Widget Function(BuildContext ControlsDetails)? controlsBuilder
:建立自定義控制元件 -
double? elevation
:相對於放置此物理物件的父級的 z 座標。預設為0.0 -
EdgeInsetsGeometry? margin
:外邊距
Stepper(
currentStep: _index,
onStepCancel: () {
if (_index > 0) {
setState(() {
_index -= 1;
});
}
},
onStepContinue: () {
if (_index <= 0) {
setState(() {
_index += 1;
});
}
},
onStepTapped: (int index) {
setState(() {
_index = index;
});
},
steps: <Step>[
Step(
title: const Text('步驟 1'),
content: Container(
alignment: Alignment.centerLeft,
child: const Text('確認是否繼續?'),
),
),
const Step(
title: Text('步驟 2'),
content: Text('確定還繼續?'),
),
],
)
UnconstrainedBox
用於去除父元件的約束
它有以下幾個屬性:
-
Key? key
:標識鍵 -
Widget? child
:子元件 -
TextDirection? textDirection
:文字方向 -
AlignmentGeometry alignment
:對齊方式。預設為Alignment.center -
Axis? constrainedAxis
:保留約束的軸 -
Clip clipBehavior
:裁剪效果。預設為Clip.none
UnconstrainedBox(
constrainedAxis: Axis.vertical,
child: Container(
color: Colors.blue,
width: 150,
),
)
![Slide 16_9 - 29](F:\學習\flutter\images\Slide 16_9 - 29.png)
如果我們不使用UnconstrainedBox,直接寫Container(color: Colors.blue)
不寫寬高,會預設佔滿整個介面。當我們使用UnconstrainedBox後,Container不寫寬高就不會顯示任何東西,這裡Axis.vertical是保留垂直方向的約束,所以高度為這個介面,如果Container不寫寬度,照樣什麼都看不到。這個演示程式碼去掉UnconstrainedBox效果也是第二張圖,這裡只做該元件的講解。
WillPopScope
建立一個小部件,該小部件註冊回撥以否決使用者嘗試關閉封閉的ModalRoute
它有以下幾個屬性:
-
Key? key
:標識鍵 -
Widget child
:子元件 -
Future Function()? onWillPop
:關閉封閉的ModalRoute事件
WillPopScope(
child: Scaffold(
appBar: AppBar(title: const Text("TestWidget")),
body: const Center(
child: Text("雙擊返回鍵退出"),
)),
onWillPop: () async {
if (_lastQUitTime == null || DateTime.now().difference(_lastQUitTime!).inMilliseconds > 500) {
_lastQUitTime = DateTime.now();
return false;
} else {
Navigator.of(context).pop(true);
// await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
return true;
}
},
)