Flutter——Materia Design元件集合

江湖救急發表於2019-09-20

前言

    開發過程中,有的時候忘記元件如何使用,不得不去查詢筆記,之前學習的時候沒有好好整理出來,很零散,所以下定決心好好整理一番,把目前常用到的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常用元件分類

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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


三: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的實現需要以下元件配合完成

  1. DefaultTabController 它是TabBar和TabBarView的控制器,關聯二者的橋樑
  2. TabBar 水平選項元件
  3. Tab 選項卡子項
  4. TabBarView 選項卡對應檢視

3,案例效果

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合

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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


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

Flutter——Materia Design元件集合


結束

整個過程的整理還是有點花時間的,但是也值得,以後就方便查閱了。

案例中還有很多不足的地方需要慢慢完善,有很多屬性沒有一一列舉,後續專案中如果碰到相關屬性使用再繼續新增。

案例中如果有錯誤的地方,希望小夥伴們指正,不勝感激!


相關文章