前言
開發過程中,有的時候忘記元件如何使用,不得不去查詢筆記,之前學習的時候沒有好好整理出來,很零散,所以下定決心好好整理一番,把目前常用到的Materia相關元件做成一個集合式的部落格文章,以便時常翻閱,開發的時候再也不用到處找相關文章了。另外,可能本文的內容也不一定很全,希望小夥伴們在此基礎上再自己深耕,進一步提高自己對Materia的認識。
Materia Design介紹
Material Design 不僅僅是安卓陣營產品的設計規範和風格,甚至它鼓勵設計師和開發者把這種風格用在蘋果裝置和 windows裝置上。作為設計規範,它很包容,卻有時又非常嚴格。使用了 Material Design 的產品給人很強的統一感和秩序感。如果從歷史來看的話,Google 的產品從來沒有一個正式嚴格的視覺規範。甚至每個產品線都有自己的設計風格和自己的品牌。但2011年後,拉里佩奇掌握了 Google 的控制權後,他改變了那種過去「程式設計師主導一切」的情況,他召集了谷歌最好的設計師一起重新設計了所有產品的語言,終於在2014年的 Google I/O 上推出了 Material Design,宣告 Google 重視設計的時代來了。Google旗下的電腦、穿戴裝置、電視等裝置都可以使用 Material Design 作為視覺規範,甚至 Google 鼓勵開發者在 iOS平臺也使用 Material Design。Google 的 Material Design 並不是簡單的扁平設計,而是一種注重卡片式設計、紙張的模擬、使用了強烈對比色彩的設計風格。這種風格形成了獨一無二的 Material Design。Material Design 的目標是建立一種優秀的設計原則和科學技術融合的可能性(Create)、並給不同平臺帶來一致性的體驗(Unify)、並且可以在規範的基礎上突出設計者自己的品牌性(Customize)。
Material Design 並不是完全的抽象扁平風格,它從物理現實中學習了諸如質感、投影、加速度、紙張的模擬等隱喻方法,這些都會讓 Material Design 更容易被使用者理解。其實我們知道Google一直在嘗試不同的設計風格,比如很早之前的長投影設計風格、後來的扁平化設計實驗等。扁平化設計的優勢就是資訊噪音少,而缺點就是情感傳遞不足,而 Material Design似 乎是一個很好的解決方案,在最大限度保證可讀性的基礎上有一些我們熟悉的物理現實的影子。所以一定程度上它既是擬物的也是扁平的。
Flutter 中Materia Design常用元件分類
- AppBar 應用導航欄元件
- BottomNavigationBar 底部導航條元件
- TabBar 水平選項卡及檢視元件
- Drawer 抽屜元件
- FloatingActionButton 懸停按鈕元件
- FlatButton 扁平按鈕元件
- PopupMenuButton 彈出選單元件
- SimpleDialog 簡單對話方塊元件
- AlertDialog 提示對話方塊元件
- SnackBar 底部訊息提示元件
- TextField 文字框元件
- Card 卡片元件
內容準備
1,案例中用到第三方外掛OKToast,依賴如下,請自行拉取依賴導包
oktoast: ^2.1.7
複製程式碼
2,建立main.dart,案例中只需要引入單獨的元件檔案,設定到home屬性上,測試的時候自行切換不同元件檔案檢視元件效果,以MyAppBar為例。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.redAccent,
),
home: MyAppBar(),
);
}
}複製程式碼
3,案例元件檔案中,對應屬性有介紹,如需瞭解其他屬性,可在基礎上自行修改測試
一:AppBar
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
///create time : 2019/9/19/019 15:32
///create by : Administrator
///des:
class MyAppBar extends StatefulWidget {
@override
_MyAppBarState createState() => _MyAppBarState();
}
class _MyAppBarState extends State<MyAppBar> {
Widget SelectView(
IconData icon, String text, String id, BuildContext context) {
return new PopupMenuItem<String>(
value: id,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Icon(icon, color: Theme.of(context).primaryColor),
SizedBox(
width: 5.0,
),
Text(text),
],
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("首頁"),//導航欄標題
leading: IconButton( //標題前顯示的元件,通常顯示圖示
icon: Icon(Icons.home),
onPressed: () {
showToast("首頁");
}),
actions: <Widget>[ //一個Widget列表,對於常用的選單顯示到導航欄上,對應不常顯示的通常用PopupMenuButton來顯示為三個點,點選彈出二級選單
IconButton(
icon: Icon(Icons.notifications),
onPressed: () {
showToast("通知");
}),
IconButton(
icon: Icon(Icons.add),
onPressed: () {
showToast("新增");
}),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
showToast("分享");
}),
// 隱藏的選單
new PopupMenuButton<String>(
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
this.SelectView(Icons.search, '搜尋好文', 'A', context),
this.SelectView(Icons.book, '掘金小冊', 'B', context),
this.SelectView(Icons.star, '我的關注', 'C', context),
],
onSelected: (String action) {
// 點選選項的時候
switch (action) {
case 'A':
showToast("搜尋好文");
break;
case 'B':
showToast("掘金小冊");
break;
case 'C':
showToast("我的關注");
break;
}
},
),
],
),
);
}
}複製程式碼
2,案例效果
二:BottomNavigationBar
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/19/019 15:34
///create by : Administrator
///des:
class MyBottomNavigationBar extends StatefulWidget {
@override
_MyBottomNavigationBarState createState() => _MyBottomNavigationBarState();
}
class _MyBottomNavigationBarState extends State<MyBottomNavigationBar> {
List<String> navs = ["首頁", "作品", "發現", "我的"]; //導航標題集合
List<IconData> icons = [
//導航圖示集合
Icons.home,
Icons.polymer,
Icons.filter_tilt_shift,
Icons.account_circle
];
int _currentIndex = 0; //當前索引,用來切換按鈕控制
List<BottomNavigationBarItem> createBarItems() {
//建立底部導航按鈕集合
List<BottomNavigationBarItem> items = [];
for (int i = 0; i < navs.length; i++) {
items.add(
BottomNavigationBarItem(icon: Icon(icons[i]), title: Text(navs[i])));
}
return items;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("底部導航"),
),
body: Center(
child: Text(this.navs[_currentIndex]),
),
bottomNavigationBar: BottomNavigationBar(
items: createBarItems(),
currentIndex: this._currentIndex,
type: BottomNavigationBarType.fixed,
onTap: _selectTap), //底部按鈕點選回撥事件
);
}
void _selectTap(int index) {
setState(() {
this._currentIndex = index;
});
}
}
複製程式碼
2,案例效果
三:TabBar
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/19/019 15:39
///create by : Administrator
///des:
class MyTabBar extends StatefulWidget {
@override
_MyTabBarState createState() => _MyTabBarState();
}
class _MyTabBarState extends State<MyTabBar> {
static List<String> tabTitles = ["視訊", "書籍", "電腦", "工具", "創意", "手機", "藍芽"];
static List<IconData> icons = [Icons.video_call, Icons.book, Icons.computer, Icons.pan_tool, Icons.wb_incandescent,Icons.tablet_android, Icons.bluetooth];
static List<Tab> tabs = createTabs();
static List<Center> contents = [];
static List<Tab> createTabs() {
List<Tab> tabs = [];
for (int i = 0; i < tabTitles.length; i++) {
tabs.add(Tab(text: tabTitles[i],icon: Icon(icons[i])));
contents.add(Center(child: Text(tabTitles[i])));
}
return tabs;
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: tabTitles.length,
child: Scaffold(
appBar: AppBar(
title: Text("水平選項卡"),
bottom: TabBar(tabs: tabs,isScrollable: true,),
),
body: TabBarView(children: contents),
),
);
}
}複製程式碼
2,說明
TabBar的實現需要以下元件配合完成
- DefaultTabController 它是TabBar和TabBarView的控制器,關聯二者的橋樑
- TabBar 水平選項元件
- Tab 選項卡子項
- TabBarView 選項卡對應檢視
3,案例效果
四:Drawer
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/19/019 16:16
///create by : Administrator
///des:
class MyDrawer extends StatefulWidget {
@override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Drawer"),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero, //這個設定防止抽屜頭部出現一段灰色
children: <Widget>[
UserAccountsDrawerHeader( //抽屜頭部元件
accountName: Text("張三瘋"), //使用者名稱稱
accountEmail: Text("464613131@qq.com"), //使用者郵箱
currentAccountPicture: CircleAvatar( //使用者頭像
backgroundImage: AssetImage("images/zsf.jpg"),
),
),
ListTile(
leading: CircleAvatar(child: Icon(Icons.color_lens)),
title: Text("個性裝扮"),
),
ListTile(
leading: CircleAvatar(child: IconButton(icon: Icon(Icons.photo), onPressed: (){})),
title: Text("我的相簿"),
),
ListTile(
leading: CircleAvatar(child: Icon(Icons.wifi_tethering)),
title: Text("我的主題"),
),
],
),
),
body: Center(),
);
}
}
複製程式碼
2,案例效果
五:FloatingActionButton
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
///create time : 2019/9/20/020 9:00
///create by : Administrator
///des:
class MyFloatActionButton extends StatefulWidget {
@override
_MyFloatActionButtonState createState() => _MyFloatActionButtonState();
}
class _MyFloatActionButtonState extends State<MyFloatActionButton> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("懸停按鈕"),
),
body: Center(),
floatingActionButton: FloatingActionButton(
onPressed: () {
showToast("懸停按鈕");
},
tooltip: "新增文章", //按鈕提示文字 長按顯示該文字
foregroundColor: Colors.black87, //前景色
backgroundColor: Colors.yellow, //背景色
elevation: 8.0, //未點選是陰影值,預設為6.0
highlightElevation: 14.0, //點選時的陰影值,預設為12.0
shape:BeveledRectangleBorder(), //按鈕形狀,預設為圓形,預設的形狀有:CircleBorder RoundedRectangleBorder ContinuousRectangleBorder BeveledRectangleBorder
child: Icon(Icons.add)),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, //按鈕位置
);
}
}
複製程式碼
2,案例效果
六:FlatButton
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
///create time : 2019/9/20/020 9:18
///create by : Administrator
///des:
class MyFlatButton extends StatefulWidget {
@override
_MyFlatButtonState createState() => _MyFlatButtonState();
}
class _MyFlatButtonState extends State<MyFlatButton> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("扁平按鈕元件"),
),
body: Center(
child: FlatButton(
textColor: Colors.red, //按鈕文字顏色
hoverColor: Colors.blue,
onPressed: () {
showToast("我是扁平按鈕");
},
child: Text("FlatButton")),
),
);
}
}
複製程式碼
2,案例效果
七:PopupMenuButton
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/20/020 9:24
///create by : Administrator
///des:
class MyPopuMenuButton extends StatefulWidget {
@override
_MyPopuMenuButtonState createState() => _MyPopuMenuButtonState();
}
class _MyPopuMenuButtonState extends State<MyPopuMenuButton> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("彈出選單元件")),
body: Center(
child: RaisedButton(
color: Colors.blue,
onPressed: () {},
textColor: Colors.white,
child: PopupMenuButton(
child: Text("彈出選單"),
tooltip: "長按提示",
initialValue: "new", // 預設選單顯示項
padding: EdgeInsets.all(0.0),
itemBuilder: (BuildContext context) {//選單選項構造器,選單為任意型別,文字,圖示
return <PopupMenuItem<String>>[
PopupMenuItem<String>(
child: Text("熱度"),
value: "hot",
),
PopupMenuItem<String>(
child: Text("最新"),
value: "new",
),
];
},
onSelected: (String action) {//選單點選回撥
switch (action) {
case "hot":
print("熱度");
break;
case "new":
print("最新");
break;
}
},
onCanceled: () {
print("onCanceled");
},
),
),
),
);
}
}
複製程式碼
2,案例效果
八:SimpleDialog
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/20/020 10:08
///create by : Administrator
///des:
class MySimpleDialog extends StatefulWidget {
@override
_MySimpleDialogState createState() => _MySimpleDialogState();
}
class _MySimpleDialogState extends State<MySimpleDialog> {
var offAndOn = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SimpleDialog"),
),
body: Center(
child: Offstage( //用於元件是否隱藏
offstage: offAndOn,
child: SimpleDialog(
title: Text("對話方塊"),
children: <Widget>[
SimpleDialogOption(
onPressed: () {},
child: Text("第一行程式碼"),
),
SimpleDialogOption(
onPressed: () {},
child: Text("第二行程式碼"),
),
SimpleDialogOption(
onPressed: () {},
child: Text("第三行程式碼"),
),
],
))),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
offAndOn =!offAndOn;
});
},
child: Icon(Icons.bubble_chart),
tooltip: "開啟對話方塊",
),
);
}
}
複製程式碼
2,案例效果
九:AlertDialog
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
///create time : 2019/9/20/020 10:24
///create by : Administrator
///des:
class MyAlertDialog extends StatefulWidget {
@override
_MyAlertDialogState createState() => _MyAlertDialogState();
}
class _MyAlertDialogState extends State<MyAlertDialog> {
var offAndOn = true;
Widget buildButton(
String text,
Function onPressed, {
Color color = Colors.white,
}) {
return FlatButton(
color: color,
child: Text(text),
onPressed: onPressed,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AlertDialog-提示對話方塊"),
),
body: Container(
child: Offstage(
offstage: offAndOn,
child: AlertDialog(
title: Text("提示"),
elevation: 10.0,
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text("是否刪除本條記錄?"),
Text("操作不可逆,請謹慎操作!"),
],
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
showToast("確定");
setState(() {
offAndOn = !offAndOn;
});
},
child: Text("確定")),
FlatButton(
onPressed: () {
showToast("取消");
setState(() {
offAndOn = !offAndOn;
});
},
child: Text("取消")),
],
),
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
offAndOn = !offAndOn;
});
},
child: Text("彈框"),
),
);
}
}
複製程式碼
2,案例效果
3,顯示自定義Dialog
import 'package:flutter/material.dart';
///create time : 2019/9/20/020 10:56
///create by : Administrator
///des:
class MyCustomDialog extends StatefulWidget {
@override
_MyCustomDialogState createState() => _MyCustomDialogState();
}
class _MyCustomDialogState extends State<MyCustomDialog> {
Widget _dialogWidget(BuildContext context) {
return Center(
child: Container(
width: 300.0,
height: 240.0,
decoration: BoxDecoration(
color: Colors.blue,
boxShadow: [
//設定陰影
BoxShadow(
color: Colors.black54,
offset: Offset(4.0, 4.0),
blurRadius: 4.0),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
alignment: Alignment.center,
child: Text("選擇影象",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
decoration: TextDecoration.none)),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: 140.0,
height: 140.0,
child: Image.asset("images/man.jpg"),
),
Container(
width: 140.0,
height: 140.0,
child: Image.asset("images/woman.jpg"),
)
],
),
Container(
alignment: Alignment.topRight,
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
onPressed: (){
Navigator.of(context).pop("確定");
},
child: Text("確定",
style:
TextStyle(decoration: TextDecoration.none,color: Colors.white))),
FlatButton(
onPressed: (){
Navigator.of(context).pop("取消");
},
child: Text("取消",
style:
TextStyle(decoration: TextDecoration.none,color: Colors.white))),
SizedBox(width: 10.0,)
],
),
),
),
],
)),
);
}
void showCustomDialog(BuildContext context) async {
var result = await showDialog(context: context, builder: _dialogWidget);
print("result is ${result}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("自定義對話方塊"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showCustomDialog(context);
},
child: Text("彈框")),
);
}
}
複製程式碼
4,案例效果
十:SnackBar
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/20/020 13:14
///create by : Administrator
///des:
class MySnackBar extends StatefulWidget {
@override
_MySnackBarState createState() => _MySnackBarState();
}
class _MySnackBarState extends State<MySnackBar> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SnackBar"),
),
floatingActionButton: Builder(builder: (context) {
return FloatingActionButton(
onPressed: () {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("是否退出應用程式?",style: TextStyle(color: Colors.white)), //提示訊息內容
action: SnackBarAction(label: "撤銷", onPressed: () {},textColor: Colors.white,), //提示訊息執行的動作
backgroundColor: Theme.of(context).primaryColor, //訊息皮膚背景色
duration: Duration(seconds: 1), //Snackbar存在時長
));
},
child: Icon(Icons.call_missed_outgoing),
);
}),
);
}
}
複製程式碼
2,案例效果
十一:TextField
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/20/020 13:46
///create by : Administrator
///des:
class MyTextField extends StatefulWidget {
@override
_MyTextFieldState createState() => _MyTextFieldState();
}
class _MyTextFieldState extends State<MyTextField> {
TextEditingController controller = TextEditingController();
@override
Widget build(BuildContext context) {
controller.addListener((){
});
return Scaffold(
appBar: AppBar(
title: Text("TextField"),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(20.0),
child: TextField(
controller: controller,
maxLength: 30, //輸入內容最大長度
maxLines: 1, //最大行數
autocorrect: true, //是否自動更正
autofocus: false, //是否自動獲取焦點
obscureText: false, //是否為密碼
textAlign: TextAlign.left, //輸入文字排列方式
style: TextStyle(fontSize: 16.0, color: Colors.black),
onChanged: (value) {
print("input value is ${value}");
},
onSubmitted: (text) {
//輸入完成後,彈出鍵盤上點選完成時回撥
print("內容提交回撥 ${text}");
},
enabled: true, //禁止輸入
cursorColor: Colors.blue,
decoration: InputDecoration(
//新增裝飾
fillColor: Colors.blue, //填充色
prefixIcon:
Icon(Icons.supervisor_account, color: Colors.blue), //左邊圖示
hintText: "使用者名稱",
helperText: "手機/郵箱",
helperStyle: TextStyle(color: Colors.blue),
suffixIcon: IconButton(onPressed: (){controller.clear();},icon: Icon(Icons.clear,color: Colors.black38),), //右邊圖示
),
),
),
),
);
}
}
複製程式碼
2,案例效果
3,異常問題
當我們清楚輸入內容的時候,不管是用controller.text=""還是controller.clear(),都會報異常,不知道小夥伴們有沒有碰到這種情況,目前我還沒解決,希望有碰到這種情況的小夥伴給我留言,謝謝。
異常資訊如下:
W/IInputConnectionWrapper(32565): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(32565): getTextBeforeCursor on inactive InputConnection
I/flutter (32565): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (32565): The following assertion was thrown while handling a gesture:
I/flutter (32565): invalid text selection: TextSelection(baseOffset: 8, extentOffset: 8, affinity:
I/flutter (32565): TextAffinity.upstream, isDirectional: false)
I/flutter (32565):
I/flutter (32565): When the exception was thrown, this was the stack:
I/flutter (32565): #0 TextEditingController.selection= (package:flutter/src/widgets/editable_text.dart:193:7)
I/flutter (32565): #1 EditableTextState._handleSelectionChanged (package:flutter/src/widgets/editable_text.dart:1379:23)
I/flutter (32565): #2 RenderEditable._handlePotentialSelectionChange (package:flutter/src/rendering/editable.dart:388:5)
I/flutter (32565): #3 RenderEditable.selectPositionAt (package:flutter/src/rendering/editable.dart:1487:9)
I/flutter (32565): #4 RenderEditable.selectPosition (package:flutter/src/rendering/editable.dart:1459:5)
I/flutter (32565): #5 _TextFieldSelectionGestureDetectorBuilder.onSingleTapUp (package:flutter/src/material/text_field.dart:98:26)
I/flutter (32565): #6 _TextSelectionGestureDetectorState._handleTapUp (package:flutter/src/widgets/text_selection.dart:1264:16)
I/flutter (32565): #7 TapGestureRecognizer._checkUp.<anonymous closure> (package:flutter/src/gestures/tap.dart:363:49)
I/flutter (32565): #8 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
I/flutter (32565): #9 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:363:11)
I/flutter (32565): #10 TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:312:7)
I/flutter (32565): #11 _TransparentTapGestureRecognizer.rejectGesture (package:flutter/src/widgets/text_selection.dart:1466:7)
I/flutter (32565): #12 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:159:26)
I/flutter (32565): #13 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:222:20)
I/flutter (32565): #14 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
I/flutter (32565): #15 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
I/flutter (32565): #16 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
I/flutter (32565): #17 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
I/flutter (32565): #21 _invoke1 (dart:ui/hooks.dart:263:10)
I/flutter (32565): #22 _dispatchPointerDataPacket (dart:ui/hooks.dart:172:5)
I/flutter (32565): (elided 3 frames from package dart:async)
I/flutter (32565):
I/flutter (32565): Handler: "onTapUp"
I/flutter (32565): Recognizer:
I/flutter (32565): _TransparentTapGestureRecognizer#cf2ed
I/flutter (32565): ════════════════════════════════════════════════════════════════════════════════════════════════════
複製程式碼
十二:Card
1,元件檔案程式碼示例
import 'package:flutter/material.dart';
///create time : 2019/9/20/020 14:52
///create by : Administrator
///des:
class MyCard extends StatefulWidget {
@override
_MyCardState createState() => _MyCardState();
}
class _MyCardState extends State<MyCard> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Card 卡片元件"),
),
body: Center(
child: SizedBox(
height: 180.0,
child: Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Item("湖北省武漢市洪山區珞喻路718號","湖北省通訊局",Icons.home),
Divider(height: 1.0,color: Colors.black26),
Item("湖北省武漢市蔡甸區華源商務廣場","武漢市杰特培訓機構",Icons.school),
],
),
),
),
),
);
}
}
class Item extends StatelessWidget{
String title;
String subTitle;
IconData icon;
Item(this.title, this.subTitle, this.icon);
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(title,style: TextStyle(fontWeight: FontWeight.w300)),
subtitle: Text(subTitle),
leading: Icon(icon,color: Colors.lightBlue),
);
}
}複製程式碼
2,案例效果
結束
整個過程的整理還是有點花時間的,但是也值得,以後就方便查閱了。
案例中還有很多不足的地方需要慢慢完善,有很多屬性沒有一一列舉,後續專案中如果碰到相關屬性使用再繼續新增。
案例中如果有錯誤的地方,希望小夥伴們指正,不勝感激!