Flutter基础

Drawer使用

mainPage.dart

// ignore_for_file: unused_import, prefer_const_constructors, prefer_const_literals_to_create_immutables

import 'package:flutter/material.dart';
import 'widget/drawerPage.dart';

main() => runApp(myApp());

class myApp extends StatelessWidget {
  const myApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "myApp",
      home: DrawerPage(),
      // 设置默认路由,如果没有该路由,则会报错
      initialRoute: '/hemo',
      // 这里配置路由表,键-》路由名,值-》跳转的页面
      routes: {
        '/main': (BuildContext context) => MainPage(),  
        '/news': (BuildContext context) => NewsPage(),
        '/drawer':(BuildContext context) => DrawerPage(),
      },
      // 设置默认路由,pageBuilder第三个参数是两根下划线
      onGenerateRoute: (setting){
        return PageRouteBuilder(pageBuilder: (BuildContext,_,__){
          return DrawerPage();
        });
      },
      // theme设置主题
      theme: ThemeData(
        // 设置全局主题颜色
        primarySwatch: Colors.green,
        primaryColor: Colors.orange,
        accentColor: Colors.pink,
        shadowColor: Colors.purple
        ),
      
      // 右上角debug图标
      debugShowCheckedModeBanner: false,
    );
  }
}

drawerPage.dart

// ignore_for_file: unused_import, file_names, prefer_const_constructors, prefer_const_literals_to_create_immutables, use_key_in_widget_constructors, deprecated_member_use

import 'package:flutter/material.dart';

class DrawerPage extends StatelessWidget {
  var selector = 0;
  List _list = ["游泳馆", "羽毛球场", "篮球场", "拳击场"];

  List _result() {
    return _list
        .map((itme) => ListTile(
              title: Text(itme),
              leading: Icon(Icons.sports_soccer),
              subtitle: Text("挥洒汗水逐梦的土地"),
              onTap: () {},
            ))
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("DrawerPage"),
        // 添加图标按钮,并为它绑定点击事件,用于打开Drawer
        leading: Builder(builder: (BuildContext context){
          return IconButton(icon: Icon(Icons.list), onPressed: () { 
            Scaffold.of(context).openDrawer();
           },);
        },),
        elevation: 15.0,
      ),
      
      // 添加底部状态栏的三个切换按钮,其中itmes的个数
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: Icon(
                Icons.add_a_photo,
              ),
              title: Text("照相")),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.center_focus_strong,
              ),
              title: Text("扫码")),
          BottomNavigationBarItem(
              icon: Icon(Icons.safety_divider), title: Text("pay"))
        ],
        // 获取底部 BottomNavigationBarItem的索引下标
        onTap: (value) {
          selector = value;
          print(value);
        },
        // 设置底部选择,结合点击事件可以切换选项
        currentIndex: selector,
      ),
      
      // 添加左侧侧边栏
      drawer: Drawer(
        // 添加listView
        child: ListView(
          children:
              // 使用遍历方式将数据取出放入children,注意这个这个函数是widget数组,不需要加中括号
              // _result(),
            [
              UserAccountsDrawerHeader(accountName: Text("泸州彭于晏"), accountEmail: Text("[email protected]"),currentAccountPicture: CircleAvatar(backgroundImage: AssetImage("images/girl.jpg"),),onDetailsPressed: ()=>print("你点击用户名片"),),
              ListTile(title: Text("学校"),leading: Icon(Icons.school),subtitle: Text("充满师生情怀的圣地"),onTap: ()=>print("你点击了学校"),),
              ListTile(title: Text("食堂"),leading: Icon(Icons.dining),subtitle: Text("皆是学生恋爱的宝地"),onTap: ()=>print("你点击了食堂"),),
              ListTile(title: Text("操场"),leading: Icon(Icons.sports_soccer),subtitle: Text("挥洒汗水逐梦的土地"),onTap: (){},),
          ]
        ),
      ),
      
      // floatingActionButton 添加浮动圆形按钮组件
      floatingActionButton: FloatingActionButton(onPressed: () { print("你点击了打印按钮"); },
      child: Icon(Icons.print),
      // 长按提示文本
      tooltip: '打印文档',
      // 设置前景色,默认是白色
      foregroundColor: Colors.red,
      // 设置背景色,默认是洋红色
      backgroundColor: Colors.teal,
      // 设置焦点颜色
      focusColor: Colors.orange,
      // 设置点击时的阴影颜色
      highlightElevation: 30,
      // 设置没有点击时的阴影颜色
      elevation: 30,
      // 设置图标为mini类型
      mini: true,
      ),
      
      // 设置浮动图标的显示位置
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      
      // 允许底部Button,这里面可以添加多个Button,使用的不多
      persistentFooterButtons: [
        FlatButton(onPressed: (){print("确定");}, child: Text("确定")),
        TextButton(onPressed: (){print("取消");}, child: Text("取消"))
      ],
    );
  }
}

在这里插入图片描述

text

Flutter基础_第1张图片

TextFeild

// ignore_for_file: file_names, unused_import, prefer_const_constructors

import 'package:flutter/material.dart';

class TextFieldDemo extends StatelessWidget {
  const TextFieldDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TextFieldDemo"),
      ),
      body: TextFieldPage(),
    );
  }
}

class TextFieldPage extends StatelessWidget {
  // 创建一个InputDecoration对象,在后面内容中直接使用该对象
  InputDecoration inputDecoration = InputDecoration(
          icon: Icon(Icons.person),
          labelText: "用户名",
          // 设置labelText的浮动标签行为,never为永不,auto为自动,always为永远展示
          floatingLabelBehavior: FloatingLabelBehavior.never,
          // 设置label的样式
          labelStyle: TextStyle(color: Colors.greenAccent),
          // 设置
          helperText: "用户名只能是字母、数字、下划线",
          errorText: "对不起,你输入的用户名中包含了。。。",
          // 设置输入框的提示文本
          hintText: "请输入用户名",
          // 设置输入框提示文本的样式
          hintStyle: TextStyle(color: Colors.orangeAccent),
          // 设置前置显示文本、图标
          prefixText: "0831",
          prefixIcon: Icon(Icons.phone_android),
          // 设置后置显示文本、图标
          suffixText: "中国",
          suffixIcon: Icon(Icons.flag),
          // 设置输入框右下方显示的文本
          // counterText: "文本有10个字吗?",
          // 设置输入框右下角的小组件,该位置只能有一个组件
          counter: Icon(Icons.question_answer),
          // 设置是否填充
          filled: true,
          // 设置填充颜色
          fillColor: Colors.grey[200],
        );

  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextField(
        // 设置输入的字符数,超出该长度之后无法输入
        maxLength: 10,
        // 设置输入的字符达到长度的时候,还可以继续输,会在文本框右下角提示
        maxLengthEnforced: false,
        // 设置输入的行数
        maxLines: 1,
        // 设置隐藏输入的内容,产用于密码,maxlines为多行时会报错
        obscureText: false,
        // 设置长按之后是否出现“剪切/复制/粘贴”菜单
        enableInteractiveSelection: false,
        // 设置输入字符的大小写,必须是模拟器上面的键盘才可以自动改变大小写
        textCapitalization: TextCapitalization.words,
        // 设置输入内容时软键盘的类型,如:text、url、dateTime、number、phone、emailAddress、name、
        keyboardType: TextInputType.text,
        // 设置键盘上动作按钮的的类型
        textInputAction: TextInputAction.search,

        // 事件
        // 输入框输入文本发生变化发生变化是回调方法
        onChanged: (value) {
          print("onChanged:" + value);
        },
        // 点击搜索框时返回的回调
        onTap: () {
          print("onTap:" + "你点击了搜索框");
        },
        // 设置点击键盘的动作按钮时的回调
        onEditingComplete: () {
          print('onEditingComplete:' + "你在键盘上点击了提交");
        },
        // 参数就是你输入的值
        onSubmitted: (value) {
          print("onsubmitted:" + value);
        },

        decoration: inputDecoration,

        // 设置输入框的修饰    调用上面定义的对象
      //   decoration: InputDecoration(
      //     prefixIcon: Icon(Icons.phone),
      //     prefixText: "0836",

      //     // 设置只有下边框线的输入框样式,不常用
      //     // border: UnderlineInputBorder(
      //     //   borderRadius: BorderRadius.all(Radius.circular(20)),
      //     //   borderSide: BorderSide(color: Colors.red),
      //     // ),

      //     // 控制输入框外边框样式的常用属性,常用
      //     enabledBorder: OutlineInputBorder(
      //         borderRadius: BorderRadius.all(Radius.circular(10)),
      //         borderSide: BorderSide(
      //             color: Colors.orangeAccent,
      //             width: 6,
      //             style: BorderStyle.solid)),

      //     // 设置获得焦点之后的边框样式
      //     focusedBorder: OutlineInputBorder(
      //         borderRadius: BorderRadius.all(Radius.circular(5)),
      //         borderSide: BorderSide(
      //           color: Colors.pink,
      //           width: 10,
      //         )),
      //   ),
      // ),
    )
    );
  }
}

TextFeilfdController

Flutter基础_第2张图片

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  // 定义初始值
  String info ="初始值";
  // 定义一个controller对象之后,整个类里面都可以使用,并且将它与TextFeild的controller进行绑定
  TextEditingController controller1 = TextEditingController();
  // 创建一个方法并重写setState方法,告诉脚手架进行重写绘制该界面
  void getValue(){
    setState(() {
      // 取出controller1的值赋值给info变量,进行传递给Text进行显示
      info = controller1.text;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "ContorllerDemo",
        ),
      ),
      body: Column(
        children: [
          TextField(controller: controller1,),
          Text(info),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: Text("确定"),
        onPressed: () {
          getValue();
        },
      ),
    );
  }
}

在这里插入图片描述

Button

RaisedButton --漂浮按钮

// 漂浮按钮
RaisedButton(
            onPressed: () {}, // 单击事件,
            child: Text("漂浮按钮"), // 设置按钮文本
            textColor: Colors.blue, // 设置按钮颜色
            highlightColor: Colors.lightGreen[100], // 设置长按按钮颜色
            splashColor: Colors.orangeAccent, // 设置水波纹颜色
            colorBrightness: Brightness.light, //设置高亮显示,默认不高亮
            elevation: 10,  // 设置按钮阴影高度
            highlightElevation: 50,// 设置高亮时的阴影颜色
            // 带水波纹高亮变化的回调函数,按下为true,松开
            onHighlightChanged: (value) {
              print(value);
            }, // 按钮名称
          ),

Flutter基础_第3张图片

// ignore_for_file: unused_import, file_names, prefer_const_constructors, prefer_const_literals_to_create_immutables

import 'package:flutter/material.dart';

class buttonDemo extends StatelessWidget {
  const buttonDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("buttonDemo"),
        elevation: 10.0,
        leading: Icon(Icons.menu),
        actions: [Icon(Icons.settings)],
      ),
      body: buttonPage(),
    );
  }
}

class buttonPage extends StatelessWidget {
  const buttonPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          RaisedButton(
            // 设置漂浮按钮
            onPressed: () {}, // 单击事件,
            child: Text("漂浮按钮"), // 设置按钮文本
            textColor: Colors.blue, // 设置按钮颜色
            highlightColor: Colors.lightGreen[100], // 设置长按按钮颜色
            splashColor: Colors.orangeAccent, // 设置水波纹颜色
            colorBrightness: Brightness.light, //设置高亮显示,默认不高亮
            elevation: 10, // 设置按钮阴影高度
            highlightElevation: 50, // 设置高亮时的阴影颜色
            // 带水波纹高亮变化的回调函数,按下为true,松开
            onHighlightChanged: (value) {
              print(value);
            }, // 按钮名称
          ),
          // 漂浮按钮
          FlatButton(
            onPressed: () {}, // 设置漂浮按钮
            child: Text("扁平按钮"), // 点击事件
            textColor: Colors.deepOrange, //文本颜色
            height: 50, // 按钮高度
            color: Colors.lightGreen[100], //设置背景颜色
          ),

          //带图标的漂浮按钮
          FlatButton.icon(
            // 带图标的漂浮按钮
            onPressed: () {},
            icon: Icon(Icons.add),
            label: Text("添加"),
            color: Colors.blueGrey,
            textColor: Colors.white,
          ),

          // 边框按钮
          OutlineButton(
            // 有边框不带阴影的按钮,用的比较少
            // 单击事件
            onPressed: () {
              print("你点击了outlineButton");
            },
            // 设置长按事件
            onLongPress: () {
              print("你长按了outlineButton");
            },
            child: Column(
              children: [Icon(Icons.input), Icon(Icons.outbox)],
            ),
            color: Colors.green,
            focusColor: Colors.black45,
            textColor: Colors.green,
            padding: const EdgeInsets.all(30.0), // 设置按钮的内边距
            borderSide: BorderSide(color: Colors.red),
          ),

          // 图标按钮
          IconButton(
            onPressed: () {}, // 按钮点击事件
            icon: Icon(Icons.home), // 按钮图标
            color: Colors.green[200], // 按钮颜色
            iconSize: 30.0, // 按钮大小
            padding: const EdgeInsets.all(30.0), // 按钮内边距
            tooltip: "home", // 长按显示提示文本
          ),

          // 文本按钮
          TextButton(onPressed: () {}, child: Text("文本按钮"),)
        ],
      ),
    );
  }
}

在这里插入图片描述

登录页面

Flutter基础_第4张图片

// ignore_for_file: file_names, unused_import, prefer_const_constructors, prefer_const_literals_to_create_immutables

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';

class LoginDemo extends StatefulWidget {
  const LoginDemo({Key? key}) : super(key: key);

  @override
  _LoginDemoState createState() => _LoginDemoState();
}

class _LoginDemoState extends State<LoginDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("登录页面"),
        leading: Icon(Icons.menu),
      ),
      body: LoginPage(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Text("确定"),
      ),
    );
  }
}

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  // 添加类的成员变量
  // 添加user控制器
  TextEditingController userEditingController = TextEditingController();
  // 添加password控制器
  TextEditingController passwordEditingController = TextEditingController();
  // 邮箱正则表达式,常用
  var emailReg = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$";
  // 设置错误提示信息
  String errorElimail = "邮箱格式有误";
  String errorPassword = "输入的密码是否超过8个字符";
  // 用户名一开始为空
  String username = "";
  String password = "";
  String userPassword = "";

  // 定义outlineinputBorder变量,方便后面多个属性使用
  // 定义启动前输入框样式
  OutlineInputBorder outlineInputBorder = OutlineInputBorder(
      borderRadius: BorderRadius.all(
        Radius.circular(10),
      ),
      borderSide: BorderSide(width: 2, color: Colors.grey));
  // 定义获得焦点时,输入框样式
  OutlineInputBorder focuslineInputBorder = OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(10)),
      borderSide: BorderSide(width: 2, color: Colors.orangeAccent));
  // user监听焦点事件,获得焦点和失去焦点
  FocusNode _focusNode = FocusNode();
  // password监听事件,获得焦点和失去焦点
  FocusNode _passwordFocusNode = FocusNode();

  // 初始化State时候
  @override
  void initState() {
    // 用户框焦点检测,并根据获得焦点与没有获得焦点设置输入框状态
    _focusNode.addListener(() {
      // 如果user失去焦点,在前面加上 感叹号表示非
      if (!_focusNode.hasFocus) {
        setState(() {
          // 判断邮箱是否获得焦点
          username = userEditingController.text; // 取出输入的字符
          print("邮箱:" + username);
          // 判断输入的内容是否符合正则表达式规则
          if (!RegExp(emailReg).hasMatch(username)) {
            // 焦点挪开时,输出错误信息
            errorElimail = "邮箱格式有误";
          }
        });
      } else {
        // 否则获得焦点
        setState(() {
          // 设置获得焦点之后,输出的错误信息为空
          errorElimail = " ";
        });
      }
    });
    // 密码框焦点检测,并根据获得焦点与没有获得焦点设置输入框状态
    _passwordFocusNode.addListener(() {
      if (!_passwordFocusNode.hasFocus) {
        setState(() {
          // 判断密码框是否获得焦点
          password = passwordEditingController.text; // 取出输入的字符
          print("密码:" + password);
          // 焦点挪开时,输出错误信息
          errorPassword = "请输入正确的密码!";
        });
      } else {
        // 否则未获得焦点
        setState(() {
          // 设置获得焦点之后,输出的错误信息为空
          errorPassword = " ";
        });
      }
    });
  }

  // 判断密码是否超过8个字符长度
  void judgePassword(value) {
    setState(() {
      if (value.length > 8) {
        errorPassword = "密码不能超过8个字符";
      }
    });
  }

  void showInfo() {
    String msg = "登录成功";
    var uname = userEditingController.text;
    var upwd = passwordEditingController.text;
    if (uname.length == 0 || upwd.length == 0) {
      msg = "邮箱名或密码不能为空";
    } else if (uname != "[email protected]") {
      msg = "邮箱名有误";
    } else if (upwd != '123456') {
      msg = "密码错误";
    } else if (uname == "[email protected]" && upwd == '123456') {
      msg = msg;
    }
    // 设置吐司
    Fluttertoast.showToast(
        msg: msg, // 显示内容
        toastLength: Toast.LENGTH_SHORT, //吐司显示的时间长度
        // gravity: ToastGravity.CENTER, // 吐司的显示位置
        // backgroundColor: Colors.red,  // toast的背景颜色
        // textColor: Colors.red,  // 
        );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 标题
        Text(
          "邮箱账号登录",
          style: TextStyle(
              color: Colors.black,
              fontSize: 18,
              fontWeight: FontWeight.bold,
              height: 5),
        ),
        // 用户名输入框
        TextField(
          focusNode: _focusNode,
          // 为收搜索框添加控制器
          controller: userEditingController,
          // 定义白名单,使用正则表达式设置输入内容格式
          inputFormatters: [
            WhitelistingTextInputFormatter(RegExp("[a-zA-Z0-9@.]"))
          ],

          decoration: InputDecoration(
            counterText: errorElimail, // 设置计数器文本信息,提示是否达到输入要求
            counterStyle: TextStyle(color: Colors.red, fontSize: 13),
            icon: Icon(Icons.person), // 设置文本框的前置图标
            hintText: "请输入账号", // 输入框提示文本
            enabledBorder: outlineInputBorder, // 用户名输入框启动时的样式
            focusedBorder: focuslineInputBorder, // 用户名输入框获得焦点之后的样式
          ),
        ),
        // 密码输入框
        TextField(
          focusNode: _passwordFocusNode,
          controller: passwordEditingController,
          onChanged: (value) {
            userPassword = value;
            // 调用一个判断密码长度的方法,若是密码不超过8个字符,则不显示,如果超过8个字符,则显示“密码超过8个字符”
            judgePassword(value);
          },
          // obscureText: true, // 设置输入内容是否隐藏
          decoration: InputDecoration(
              hintText: "请输入密码", // 设置输入框提示文本
              counterText: errorPassword, // 设置计数器文本信息,提示是否达到输入要求
              counterStyle: TextStyle(color: Colors.red, fontSize: 13),
              enabledBorder: outlineInputBorder, // 密码框启动时的样式
              focusedBorder: focuslineInputBorder, // 密码框获得焦点之后的样式
              icon: Icon(Icons.lock_open_sharp)),
        ),
        RaisedButton(
          // 设置按钮点击事件,当点击按钮时调用 toast
          onPressed: () {
            showInfo();
          },
          child: Text("登 录"),
          color: Colors.lightGreen[200],
        ),
        Text("忘记密码?| 注册新账号")
      ],
    );
  }
}

Flutter基础_第5张图片Flutter基础_第6张图片

Checkbox复选框

// ignore_for_file: file_names, unused_import, prefer_const_constructors, prefer_const_literals_to_create_immutables

import 'package:flutter/material.dart';

class checkBoxDemo extends StatefulWidget {
  const checkBoxDemo({Key? key}) : super(key: key);

  @override
  _checkBoxDemoState createState() => _checkBoxDemoState();
}

class _checkBoxDemoState extends State<checkBoxDemo> {
  // 使用list存放每一个checkbox的值,选中为true,
  List flag = [false, true, false, false];
  //
  List like = ["网球王子", "足球宝贝", "数码宝贝"];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("checkBoxDemo"),
        leading: Icon(Icons.menu),
        actions: [Icon(Icons.settings)],
        centerTitle: true,
      ),
      body: Row(
        children: [
          Text("爱好:"),
          Checkbox(
            // 设置checkbox的值为false,没有被选中
            value: flag[0],
            onChanged: (value) {
              // 导致state组件上的值改变时需要使用 setState改变值
              // 使用setTate 更新flag的值,选中为true,没有被选中为false
              setState(() {
                flag[0] = value!;
              });
            },
          ),
          Text("网球王子"),
          Checkbox(
            // 设置checkbox的值为false,没有被选中
            value: flag[1],
            onChanged: (value) {
              // 导致state组件上的值改变时需要使用 setState改变值
              // 使用setTate 更新flag的值,选中为true,没有被选中为false
              setState(() {
                flag[1] = value!;
              });
            },
          ),
          Text("足球宝贝"),
          Checkbox(
            // 设置checkbox的值为false,没有被选中
            value: flag[2],
            onChanged: (value) {
              // 导致state组件上的值改变时需要使用 setState改变值
              // 使用setTate 更新flag的值,选中为true,没有被选中为false
              setState(() {
                flag[2] = value!;
              });
            },
          ),
          Text("数码宝贝"),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          String info = "你的选项是:";
          for (var i = 0; i < flag.length; i++) {
            if (flag[i]) {
              info = info+like[i];
            }
          }
          print(info);
        },
        tooltip: "Increment",
        child: Icon(Icons.save),
        backgroundColor: Colors.greenAccent,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

Flutter基础_第7张图片Flutter基础_第8张图片

Checklistbox

import 'package:flutter/material.dart';

class checkBoxDemo extends StatefulWidget {
  const checkBoxDemo({Key? key}) : super(key: key);

  @override
  _checkBoxDemoState createState() => _checkBoxDemoState();
}

class _checkBoxDemoState extends State<checkBoxDemo> {
  // 使用list存放每一个checkbox的值,选中为true,
  List flag = [false, true, false, false];
  //定义爱好列表
  List like = ["网球王子", "足球宝贝", "篮球宝贝", "数码宝贝"];
  //定义子标题列表
  List subInfo = [
    "日本漫画家许斐刚的以运动为主题的漫画",
    "为比赛拉人气的拉拉队",
    "日本东映动画公司以数码怪兽为原型制作的系列动画",
    "激烈的篮球比赛之中,给赛场的紧张气氛带来些许放松的篮球拉拉队",
  ];
  //设置图标组件
  Widget icon = Icon(Icons.info);
  //设置复选框值为false
  bool isChecked = false;
  // 闭包输出多个checklist
  // List<Widget> _checklist(){
  //   return
  // }

  @override
  Widget build(BuildContext context) {
  // 创建一个column对象,目的放多个值
    Column column = Column(
      children: [
        CheckboxListTile(
          value: isChecked,
          onChanged: (value) {
            setState(
              () {
                isChecked = value!;
                // 当全选按钮被选中时,其余复选框的flag值与该复选框值相同
                for (var i = 0; i < flag.length; i++) {
                  flag[i] = isChecked;
                }
              },
            );
          },
          title: Text(
            "全选",
            style: TextStyle(color: Colors.lime),
          ), // 设置checklist的标题
          subtitle: Text("全选表示全部选中"), // 设置checklist的子标题
          secondary: Icon(Icons.flag), // 设置checklist的图标
          // controlAffinity: ListTileControlAffinity.trailing,// 反转,复选框在前
        ),
        CheckboxListTile(
          value: flag[0],
          onChanged: (value) {
            setState(() {
              flag[0] = value!;
              print("你选中了" + like[0]);
            });
          },
          title: Text(like[0]),
          subtitle: Text(subInfo[0]),
          secondary: icon,
        ),
        CheckboxListTile(
          value: flag[1],
          onChanged: (value) {
            setState(() {
              flag[1] = value!;
              print("你选中了" + like[1]);
            });
          },
          title: Text(like[1]),
          subtitle: Text(subInfo[1]),
          secondary: icon,
        ),
        CheckboxListTile(
          value: flag[2],
          onChanged: (value) {
            setState(() {
              flag[2] = value!;
              print("你选中了" + like[2]);
            });
          },
          title: Text(like[2]),
          subtitle: Text(subInfo[2]),
          secondary: icon,
        ),
        CheckboxListTile(
          value: flag[3],
          onChanged: (value) {
            setState(() {
              flag[3] = value!;
              print("你选中了" + like[3]);
            });
          },
          title: Text(like[3]),
          subtitle: Text(subInfo[3]),
          secondary: icon,
        ),
      ],
    );

    return Scaffold(
      appBar: AppBar(
        title: Text("checkBoxDemo"),
        leading: Icon(Icons.menu),
        actions: [Icon(Icons.settings)],
        centerTitle: true,
      ),

      // body: row,  //调用row对象
      body: column,
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          String info = "你的选项是:";
          for (var i = 0; i < flag.length; i++) {
            if (flag[i]) {
              info = info + like[i];
            }
          }
          print(info);
        },
        tooltip: "Increment",
        child: Icon(Icons.save),
        backgroundColor: Colors.greenAccent,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

Flutter基础_第9张图片Flutter基础_第10张图片

showDatePicker

import 'package:flutter/material.dart';

class showDatePickerDemo extends StatefulWidget {
  const showDatePickerDemo({Key? key}) : super(key: key);

  @override
  _showDatePickerDemoState createState() => _showDatePickerDemoState();
}

class _showDatePickerDemoState extends State<showDatePickerDemo> {
  // 获取当前年月日
  String date = DateTime.now().toString().substring(0, 10);
  //定义一个弹出日期的选择器,该方法返回类型是 Future<DateTime?> 类型,
  // showDatePicker是一个异步调用方法,需要用async修饰,异步调用需要等它执行完,所以使用await
  //注意防止空类型,且使用 ? 进行强制类型转换
  Future<DateTime?> showDate(context) async {
    DateTime? d = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2000, 01, 01),
        lastDate: DateTime(2055, 12, 21),
        // 
        builder: (context,child){
          return Scaffold(appBar: AppBar(title: Text("选择出身日期"),),body: child,)
        });
    setState(() {
      date = d.toString().substring(0, 10);
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("showDatePickerDemo"),
        leading: Icon(Icons.menu),
        actions: [Icon(Icons.settings)],
        centerTitle: true,
      ),
      body: Text(time),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 为了程序的可读性,在外部定义该方法,且因build方法是widget类型,传入的参数时context,所以该方法的参数也需要为context
          showTime(context);
        },
        child: Icon(Icons.flag),
      ),
    );
  }
}  

Flutter基础_第11张图片

showTimePicker

import 'package:flutter/material.dart';

class showDatePickerDemo extends StatefulWidget {
  const showDatePickerDemo({Key? key}) : super(key: key);

  @override
  _showDatePickerDemoState createState() => _showDatePickerDemoState();
}

class _showDatePickerDemoState extends State<showDatePickerDemo> {
  // 获取当前时间
  String time = TimeOfDay.fromDateTime(DateTime.now()).toString();
  // 定义一个弹出时间选择器的方法,返回类型可能是 null,需要使用 ? 进行修饰
  Future<TimeOfDay?> showTime(context) async {
    // 使用 ? 进行强制类型转换
    TimeOfDay? t = await showTimePicker(
        context: context, initialTime: TimeOfDay.fromDateTime(DateTime.now()),
        builder: (context,child){
          return Scaffold(appBar: AppBar(title: Text("选择出身日期"),),body: child,)
        });
    setState(() {
      //根据period方法判断上午下午,并使用问号表达式进行判断
      String s = t!.period.toString() == 'DayPeriod.am' ? '上午' : '下午';
      // 分别取出 时 、分变成string类型进行输出
      time = s + t.hour.toString() + ':' + t.minute.toString();
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("showDatePickerDemo"),
        leading: Icon(Icons.menu),
        actions: [Icon(Icons.settings)],
        centerTitle: true,
      ),
      body: Text(time),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 为了程序的可读性,在外部定义该方法,且因build方法是widget类型,传入的参数时context,所以该方法的参数也需要为context
          showDate(context);
        },
        child: Icon(Icons.flag),
      ),
    );
  }
}

Flutter基础_第12张图片

国际化

pubspec.yaml文件中修改配置,

dependencies:
  flutter_localizations:  # 添加
    sdk: flutter  #添加

在main文件中修改,

MaterialApp(
      // 将英文变成中文显示
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: [
        const Locale('zh','CH'),
        const Locale('en','US'),
      ],
      locale: Locale('zh'),

效果:
Flutter基础_第13张图片

RichText与TextSpan

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

class RichTextDemo extends StatefulWidget {
  const RichTextDemo({Key? key}) : super(key: key);

  @override
  _RichTextDemoState createState() => _RichTextDemoState();
}

class _RichTextDemoState extends State<RichTextDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("RichTextDemo"),
        leading: Icon(Icons.menu),
      ),
      body: RichText(
          text: TextSpan(
              text: "每个TextSpan都可以设置单独的样式",
              style: TextStyle(color: Colors.red,fontSize: 18),
              children: [
            TextSpan(
                text: "我是黑色",
                style: TextStyle(color: Colors.black, fontSize: 30)),
            // 子标签没有设置样式会使用父标签的样式
            TextSpan(text: "我的样式和父标签样式相同"),
            TextSpan(
                text: "点击试试",
                style: TextStyle(color: Colors.blue, fontSize: 15),
                // 识别,点击事件.
                recognizer: TapGestureRecognizer()
                  ..onTap = () {
                    // 语法糖
                    Fluttertoast.showToast(msg: "你点击了文字");
                    print("啥都没有");
                  }),
            TextSpan(
                text: "噢噢噢噢",
                style: TextStyle(color: Colors.green, fontSize: 22))
          ])),
    );
  }
}

Flutter基础_第14张图片

Flutter基础_第15张图片

图片浏览器

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

class pictureBrowserDemo extends StatefulWidget {
  const pictureBrowserDemo({Key? key}) : super(key: key);

  @override
  _pictureBrowserDemoState createState() => _pictureBrowserDemoState();
}

class _pictureBrowserDemoState extends State<pictureBrowserDemo> {
  Object selected = 4;
  // 定义图片列表
  static List piclist = [
    "images/girl.jpg",
    "images/pic2.jpg",
    "images/pic3.jpg",
    "images/pic4.jpg",
    "images/pic5.jpg",
    "images/pic6.jpg",
    "images/pic7.jpg",
  ];
  // 定义索引
  static var index = 2;
  //
  static var colorsVlue = 0.0;
  @override
  Widget build(BuildContext context) {
    // 添加图片
    Widget picture = Image.asset(piclist[index]);

    Slider slider = Slider(
        value: colorsVlue,
        min: 0,
        max: 255,
        onChanged: (value) {
          setState(() {
            colorsVlue = value;
          });
        });
    return Scaffold(
      appBar: AppBar(
        title: Text("图片浏览器"),
      ),
      body: Column(
        children: [
          // 定义图片显示区
          Container(
            child: picture,
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height / 3,
            color: Color.fromARGB(255, 235, 173, 199),
          ),
          RadioListTile(
              value: 0,
              title: Text("混色"),
              subtitle: Column(
                children: [Text("拖动滑块产生混色原色"), slider],
              ),
              groupValue: selected,
              onChanged: (value) {
                setState(() {
                  selected = value!;
                  picture = Image.asset(
                    piclist[index],
                    color: Colors.yellow,
                    colorBlendMode: BlendMode.color,
                  );
                });
              }),
          RadioListTile(
              value: 1,
              title: Text("拉伸"),
              subtitle: Text("拉伸某个区域"),
              groupValue: selected,
              onChanged: (value) {
                setState(() {
                  selected = value!;
                  picture = Image.asset(
                    piclist[index],
                    centerSlice: Rect.fromLTRB(2, 2, 2, 2),
                  );
                });
              }),
          RadioListTile(
              value: 2,
              title: Text("圆边"),
              subtitle: Text("显示圆角边"),
              groupValue: selected,
              onChanged: (value) {
                setState(() {
                  selected = value!;
                  picture = ClipOval(
                    child: Image.asset(
                      piclist[index],
                      fit: BoxFit.cover,
                    ),
                  );
                });
              }),
          RadioListTile(
              value: 3,
              title: Text("原图"),
              subtitle: Text("显示原图"),
              groupValue: selected,
              onChanged: (value) {
                setState(() {
                  selected = value!;
                });
              }),
          RadioListTile(
              value: 4,
              title: Text("平铺"),
              subtitle: Text("将图像按XY轴方向平铺"),
              groupValue: selected,
              onChanged: (value) {
                setState(() {
                  selected = value!;
                  picture = Image.asset(
                    piclist[index],
                    repeat: ImageRepeat.repeat,
                  );
                });
              }),
          Container(
            color: Colors.black12,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                RaisedButton(
                  onPressed: () {
                    setState(() {
                      if (index > 0) {
                        index--;
                      } else {
                        Fluttertoast.showToast(
                            msg: "已经是第一张图片了!", toastLength: Toast.LENGTH_SHORT);
                      }
                      picture = Image.asset(piclist[index]);
                    });
                  },
                  child: Text("向前"),
                ),
                RaisedButton(
                  onPressed: () {
                    setState(() {
                      if (index < piclist.length - 1) {
                        index++;
                      } else {
                        Fluttertoast.showToast(
                            msg: "已经是最后一张图片了!",
                            toastLength: Toast.LENGTH_SHORT);
                      }
                      picture = Image.asset(piclist[index]);
                    });
                  },
                  child: Text("向后"),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

Flutter基础_第16张图片

数据库的使用

在pubspec.yaml文件中添加依赖:

dependencies:
  sqflite: ^2.0.2

注意:添加完依赖之后需要重启模拟器!

创建按钮组件,将点击事件用于触发函数。

ElevatedButton(
            onPressed: () {
              触发事件方法;
            },

输出数据库存放位置

创建一个void getDBPath()方法,getDatabasesPath()可以得到数据库默认位置。

// 注意getDatabasesPath方法是异步方法,外部函数应使用async修饰,await得到异步数据
  void getDBPath() async {
    String dbPath = "";	//存放数据库路径
    // 得到数据库路径,是异步操作使用await
    dbPath = await getDatabasesPath();
    print(dbPath);	// 输出数据库路径
  }

使用Future异步对象进行接收返回值,

Future path = getDatabasesPath();
	// 使用then方法进行获取异步对象值
    path.then((value){
      dbPath = value;//存放路径
      print(dbPath);
    });

这是个异步方法,需要使用await关键字进行修饰,而外部的方法需要使用async关键字进行修饰。

初始化数据库

创建一个void initDB()方法,使用openDatabase()异步方法进行打开数据库,

// 初始化数据库
  void initDB() {
    String dbPath = "";
    Future path = getDatabasesPath();
    path.then((value) async {
      db = await openDatabase("$value/school.db", 
          // 指定版本号
          version: 1,
          // 用于当数据库不存在时,进行创建表
          onCreate: (Database db, int version) {
        // 创建表结构
        String createSQL =
            'create table student(id integer auto increment, xh text primary key,xm text,age integer)';
        // 执行SQL语句
        db.execute(createSQL);
      }, // 更新版本,创建新表,若版本不改变,则不会创建新表
          onUpgrade: (Database db, int version, int id) {
        String createSQL =
            'create table student(id integer auto increment, xh text primary key,xm text,age integer)';
        // 执行SQL语句
        db.execute(createSQL);
      });
    });
  }

插入记录

使用rawInsert()异步方法进行插入记录,

This method helps insert a map of [values]
/// into the specified [table] and returns the
/// id of the last inserted row.

Future rawInsert(String sql, [List? arguments]);

页面启动就打开数据库,

// 打开页面的时,自动打开数据库,使得在插入数据之前,先打开表
@override
void initState() {
    // TODO: implement initState
    initDB();
}

点击按钮就可插入数据,

ElevatedButton(
              onPressed: () async {
                String sql =
                    'insert into student(xh,xm,age) values("20205075","蔡义","20")';
                // 生插入SQL语句,并且返回最后一条记录的编号,异步操作
                int id = await db.rawInsert(sql);
                print("插入成功,当前id为$id");
              },
              child: Text("插入记录")),

使用占位符

ElevatedButton(
              onPressed: () async {
                // 使用占位符进行占位
                String sql = 'insert into student(xh,xm,age) values(?,?,?)';
                // 数据列表,用于存放占位符所需的值
                List lists = ["20205050", "黄恒", 15];

                // 生插入SQL语句,并且返回最后一条记录的编号,异步操作
                // 第二参数为占位符的列表
                int id = await db.rawInsert(sql, lists);
                print("插入成功,当前id为$id");
              },
              child: Text("插入记录")),

使用sqflite插件自带的插入方法,

Future insert(String table, Map values,
 {String? nullColumnHack, ConflictAlgorithm? conflictAlgorithm});

代码实现:

ElevatedButton(
              onPressed: () async {
                // 使用sqflite插件自带的插入方法
                Map values = {
                  'xh': "20205051",
                  'xm':"黄勇",
                  'age':19,
                };
                int id = await db.insert("student", values);
                print("插入成功,当前id为$id");
              },
              child: Text("插入记录")),

修改记录

通过rawUpdate()异步方法进行更新记录,

Future rawUpdate(String sql, [List? arguments]);
ElevatedButton(
              onPressed: () async {
                // 更新SQL语句
                String sql = 'update student set age=37,xm="黄勇" where xh="20205051"';
                // 返回修改记录的条数
                int count = await db.rawUpdate(sql);
                print("修改了$count条记录");
              },
              child: Text("修改记录")),

使用占位符

ElevatedButton(
              onPressed: () async {
                // 占位符方式
                List lists = ["黄勇",37,"20205051"];
                String sql = 'update student set xm=?,age=? where xh=?';
                // 返回修改记录的条数
                int count = await db.rawUpdate(sql,lists);
                print("修改了$count条记录");
              },
              child: Text("修改记录")),

使用sqflite插件自带的修改方法,

Future update(
 String table, //table为表名
 Map values,//修改的值
 // 条件
 {String? where,
 List? whereArgs,
 ConflictAlgorithm? conflictAlgorithm}
);

实现方式:

ElevatedButton(
              onPressed: () async {
                // 使用sqflite插件自带的修改方法
                // 需要修改的值
                Map values = {
                  "age":37,
                  // "xm":"黄勇",
                };
                String where = "xh=? and xm=?";//条件占位符
                // 条件值
                List lists = ["20205051","黄勇"];
                //返回修改的记录
                int count = await db.update("student", values,where: where,whereArgs: lists);
                print("修改成功,修改了$count条记录");
              },
              child: Text("修改记录")),

查询记录

通过rawQuery()异步方法进行查找记录,

Executes a raw SQL SELECT query and returns a list of the rows that were found.

Future>> rawQuery(
 String sql,
 [List? arguments]
);

使用异步方法接收返回值,

ElevatedButton(onPressed: () async{
            // 查询记录
            String sql = 'select xh,xm,age from student where age=37';
            List result = await db.rawQuery(sql);
            print(result);
          }, child: Text("查询记录")),

使用then()方法接收返回值,

ElevatedButton(onPressed: () async{
            // 查询记录
            String sql = 'select xh,xm,age from student where age=37';
            db.rawQuery(sql).then((value) => print(value));
          }, child: Text("查询记录")),

使用占位符

ElevatedButton(onPressed: () async{
            List lists = [37];
            String sql = 'select xh,xm,age from student where age=?';
    		// 使用异步方法接收返回值
            List result = await db.rawQuery(sql);
            print(result);
    		// 使用then()方法接收返回值
            // db.rawQuery(sql).then((value) => print(value));
          }, child: Text("查询记录")),

使用sqflite插件提供的查询方法,

Future>> query(String table,// 表名
 {bool? distinct,// 去重
 List? columns,// 设置显示的字段
 String? where,//条件
 List? whereArgs,// 条件值
 String? groupBy,// 分组
 String? having,// 分组之后进行筛选
 String? orderBy,// 排序
 int? limit,// 限制查询记录的条数
 int? offset// 偏移量
 }
);

实现方式:

ElevatedButton(
              onPressed: () async {
				// 存放结果
                List> result = [];
                // 设置显示的字段
                List cols = ["xh", "xm"];
                // 条件占位符
                String where = 'age=? and xh=?';
                List args = [37, "20205051"];
                // result = await db.query("student",columns: cols,where: where,whereArgs: args);
				// 查找出来之后进行排序操作
                result = await db.query(
                  "student",
                  columns: cols,
                  orderBy: 'xh desc',
                  limit: 1,
                  offset: 1,
                );
                print(result);
              },
              child: Text("查询记录")
),

删除记录

通过rawDelete()异步方法进行删除记录,

Future rawDelete(String sql, [List? arguments]);
ElevatedButton(onPressed: () async{
            String sql = 'delete from student where xh="20205075"';
            int count = await db.rawDelete(sql);
            print("删除成功,共删除了$count条记录");
          }, child: Text("删除记录")),

使用占位符

ElevatedButton(onPressed: () async{
            // String sql = 'delete from student where xh="20205075"';
            List lists = ["20205075"];
            String sql = 'delete from student where xh=?';
            int count = await db.rawDelete(sql);
            print("删除成功,共删除了$count条记录");
          }, child: Text("删除记录")),

使用sqflite提供的删除方法,

Future delete(String table, {String? where, List? whereArgs});

实现效果:

ElevatedButton(onPressed: () async{
            // 使用sqflite插件进行删除
            String where = "xh=?";// 删除的条件占位符
            // 删除的条件值
            List args = ['20205050'];
            db.delete('student',where: where,whereArgs: args);
          }, child: Text("删除记录")),

关闭数据库

使用close()方法进行关闭,数据库关闭之后不能进行“增、删、改、查”操作,必须重启数据库才能进行操作。

Future close();
ElevatedButton(onPressed: (){
            db.close();
          }, child: Text("关闭数据库")),

显示数据库中所有表

使用查询语句进行查询显示出来,

ElevatedButton(
              onPressed: () async {
                String sql =
                    'select name from sqlite_master where type="table"';
                List table = await db.rawQuery(sql);
                print(table);
              },
              child: Text("显示所有表")),

删除数据库

首先使用getDatabasesPath()异步方法获取数据库存放路径,deleteDatabase()异步方法删除数据库。

Future deleteDatabase(String path) =>
 databaseFactory.deleteDatabase(path);
ElevatedButton(onPressed: () async{
            String path = await getDatabasesPath();
            await deleteDatabase("$path/school.db");
            print("删除成功!");
          }, child: Text("删除数据库")),

你可能感兴趣的:(Flutter,dart,flutter,android)