Flutter——Materia Design组件集合

2,166 阅读12分钟

前言

    开发过程中,有的时候忘记组件如何使用,不得不去查找笔记,之前学习的时候没有好好整理出来,很零散,所以下定决心好好整理一番,把目前常用到的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,案例效果



二: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的实现需要以下组件配合完成

  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(),都会报异常,不知道小伙伴们有没有碰到这种情况,目前我还没解决,希望有碰到这种情况的小伙伴给我留言,谢谢。

异常信息如下:

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



结束

整个过程的整理还是有点花时间的,但是也值得,以后就方便查阅了。

案例中还有很多不足的地方需要慢慢完善,有很多属性没有一一列举,后续项目中如果碰到相关属性使用再继续添加。

案例中如果有错误的地方,希望小伙伴们指正,不胜感激!