Flutter——Materia Design組件集合

前言

    開發過程當中,有的時候忘記組件如何使用,不得不去查找筆記,以前學習的時候沒有好好整理出來,很零散,因此下定決心好好整理一番,把目前經常使用到的Materia相關組件作成一個集合式的博客文章,以便時常翻閱,開發的時候不再用處處找相關文章了。另外,可能本文的內容也不必定很全,但願小夥伴們在此基礎上再本身深耕,進一步提升本身對Materia的認識。android

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似 乎是一個很好的解決方案,在最大限度保證可讀性的基礎上有一些咱們熟悉的物理現實的影子。因此必定程度上它既是擬物的也是扁平的。
windows

Flutter 中Materia Design經常使用組件分類

  1. AppBar 應用導航欄組件
  2. BottomNavigationBar  底部導航條組件
  3. TabBar 水平選項卡及視圖組件
  4. Drawer 抽屜組件
  5. FloatingActionButton 懸停按鈕組件
  6. FlatButton 扁平按鈕組件
  7. PopupMenuButton 彈出菜單組件
  8. SimpleDialog 簡單對話框組件
  9. AlertDialog 提示對話框組件
  10. SnackBar 底部消息提示組件
  11. TextField 文本框組件
  12. 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的實現須要如下組件配合完成bash

  1. DefaultTabController 它是TabBar和TabBarView的控制器,關聯兩者的橋樑
  2. TabBar 水平選項組件
  3. Tab 選項卡子項
  4. 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(),都會報異常,不知道小夥伴們有沒有碰到這種狀況,目前我還沒解決,但願有碰到這種狀況的小夥伴給我留言,謝謝。app

異常信息以下:less

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,案例效果



結束

整個過程的整理仍是有點花時間的,可是也值得,之後就方便查閱了。async

案例中還有不少不足的地方須要慢慢完善,有不少屬性沒有一一列舉,後續項目中若是碰到相關屬性使用再繼續添加。ide

案例中若是有錯誤的地方,但願小夥伴們指正,不勝感激!工具

相關文章
相關標籤/搜索