flutter 入门,常用组件、路由跳转

一、简单介绍

我们的代码都是编写在lib下以dart结尾的文件中,项目入口文件是main.dart,启动方法是void.main()

在每个页面中都依赖UI库 material ,Material 是一种标准的移动端和web端的UI框架,是一套google的设计规范,flutter项目以meterial为基础

一切皆为widget(组件)

  • 在 Flutter 中,一切的显示都是 Widget 。Widget 是一切的基础

  • Widget 和 Widget 之间通过 child: 进行嵌套。

  • 你需要做的就是在 widget 中堆积你的布局

import 'package:flutter/material.dart';

只有一个根函数 runApp()

void main(){
  runApp(
    //定义内容
  );
}

二、Flutter常用部件

1、Center小部件:定义一个居中的部件;Text小部件:定义文本内容;自定义部件StatelessWidget:无状态部件

import 'package:flutter/material.dart';

// 封装组件
class Hello extends StatelessWidget {
  @override
  build(BuildContext context) {
    return Center(
      child: Text(
        'gril1',
        textDirection: TextDirection.ltr,
        style: TextStyle(
          color: Colors.blue,
          fontSize: 28.0,
          fontWeight: FontWeight.w700,
          fontStyle: FontStyle.italic,
        ),
      ),
    );
  }
}
  • 文本方向

属性名意义
TextDirection.ltr左对齐
TextDirection.rtl右对齐

2、文字组件RichText (可以单独设置每个文字的样式)搭配TextSpan使用,示例如下

class WidgetTestRichText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // RichText的作用:可以单独设置每一个字体的样式,相较于Text更加灵活
    return RichText(
      text: TextSpan(
        text: '年薪百万,',
        style: TextStyle(
          color: Colors.red,
          fontSize: 22,
        ),
        children: [
          TextSpan(
            text: '就在明天,',
            style: TextStyle(
              color: Colors.black,
              fontSize: 22,
            ),
          ),
          TextSpan(
            text: '你一定行。',
            style: TextStyle(
              color: Colors.blue,
              fontSize: 22,
            ),
          ),
        ],
      ),
    );
  }
}

 3、常用布局组件 Column 垂直布局,Row水平布局  示例如下

  • Column

    • 设置垂直对齐组件

    • 设置主轴对齐方式

    • 设置交叉抽对齐方式

  • Row

    • 设置水平对齐组件

    • 设置主轴对齐方式

    • 设置交叉轴对齐方式

 

//垂直布局
class WidgetTestColumn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange[100], //颜色后面加数组里的数组可以修改颜色的鲜艳度
      width: double.infinity,
      child: Column(
        // mainAxisAlignment设置Column内的内容的位置布局:上中下,等比分布
        mainAxisAlignment: MainAxisAlignment.start,
        // crossAxisAlignment设置Column内的内容的位置在左右方向布局:左中右
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Icon内的size可以控制图标的大小
          Icon(
            Icons.settings,
            size: 50,
          ),
          Icon(
            Icons.close,
            size: 50,
          ),
          Icon(
            Icons.group,
            size: 50,
          ),
          Icon(
            Icons.architecture,
            size: 50,
          ),
          Icon(
            Icons.vibration,
            size: 50,
          ),
        ],
      ),
    );
  }
}
//水平布局
class WidgetTestRow extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange[100], //颜色后面加数组里的数组可以修改颜色的鲜艳度
      height: double.infinity,
      child: Row(
        // mainAxisAlignment设置Row内的内容的位置布局:左中右,等比分布
        mainAxisAlignment: MainAxisAlignment.end,
        // crossAxisAlignment设置Row内的内容的位置在上下方向布局:上中下
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Icon内的size可以控制图标的大小
          Icon(
            Icons.settings,
            size: 50,
          ),
          Icon(
            Icons.close,
            size: 50,
          ),
          Icon(
            Icons.group,
            size: 50,
          ),
          Icon(
            Icons.architecture,
            size: 50,
          ),
          Icon(
            Icons.vibration,
            size: 50,
          ),
        ],
      ),
    );
  }
}

4、container容器,相当于div标签

Container(
  width: 100.0,
  height: 100.0,
  color: Colors.red,
  padding: EdgeInsets.all(10.0),
  margin: EdgeInsets.all(10.0),
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: <Widget>[

    ],
  ),
)

 5、decoration容器装饰,圆角:borderRadius only 分别定义圆角 ,borderRadius circular 统一定义圆角 示例如下

  • decoration容器装饰

    • border属性

  • 分别定义边框效果

  • 统一定义边框效果

class WidgetTestContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Container是容器组件,相当于div的角色
    // 当定义的有decoration时外部不能定义color,需要将color移入decoration内
    return Container(
      margin: EdgeInsets.all(10),
      width: double.infinity, //充满整个容器的宽
      height: double.infinity, //充满整个容器的高
      // width: 300,
      // height: 300,
      decoration: BoxDecoration(
        color: Colors.pink,
        // Border.all 同时设置四条边的边框
        border: Border.all(
          color: Colors.blue,
          width: 5,
        ),
        // 以下单独设置每一边的边框
        // border: Border(
        //   bottom: BorderSide(
        //     color: Colors.blue,
        //     width: 3,
        //   ),
        //   right: BorderSide(
        //     color: Colors.blue,
        //     width: 3,
        //   ),
        //   top: BorderSide(
        //     color: Colors.blue,
        //     width: 3,
        //   ),
        // ),
        // 设置每一个角的圆角
        // borderRadius: BorderRadius.all(
        //   Radius.circular(20),
        // ),
        // 单独设置某一个角的圆角
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(5),
          topRight: Radius.circular(5),
          bottomLeft: Radius.circular(5),
          bottomRight: Radius.circular(5),
        ),
      ),
      child: Center(
        child: Text('Conatainer'),
      ),
    );
  }
}

6、AspectRatio(固定宽高比);层叠堆放部件 Stack内部属性是children,从上到下依次堆放;ListTitle设置列表,路由列表,Divider分割线;Chip tag部件 avatar设置tag前面的样式,onDeleted增加删除操作。示例如下:

import 'package:flutter/material.dart';

// 更多组件:AspectRatio(固定宽高比);层叠堆放部件 Stack内部属性是children,从上到下依次堆放;ListTitle设置列表,路由列表,Divider分割线;Chip tag部件 avatar设置tag前面的样式,onDeleted增加删除操作
class MoreWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        // 1、AspectRatio固定宽高比:aspectRatio属性是必须的
        // AspectRatio(
        //   aspectRatio: 16 / 9,
        //   child: Container(
        //     color: Colors.blue,
        //     child: Text('固定宽高比'),
        //   ),
        // ),
        AspectRatio(
          aspectRatio: 3 / 1,
          child: Container(
            child: Image.asset(
              'images/pic.jpg',
              fit: BoxFit.cover, //fit和图片配合使用,目的是使图片如何显示
            ),
          ),
        ),
        // 2、设置部件之间的间隔SizeBox
        SizedBox(
          height: 15,
          child: Text('SizeBox'),
        ),
        // 3、层叠堆放部件 Stack
        Stack(
          children: [
            Container(
              color: Colors.pink,
              width: double.infinity,
              height: 110,
            ),
            Positioned(
              right: 10,
              top: 10,
              child: Icon(
                Icons.ac_unit,
                color: Colors.white,
              ),
            ),
            Positioned(
              right: 40,
              top: 40,
              child: Icon(
                Icons.ac_unit,
                color: Colors.white,
              ),
            ),
            Positioned(
              right: 60,
              top: 60,
              child: Icon(
                Icons.ac_unit,
                color: Colors.white,
              ),
            ),
            Positioned(
              right: 80,
              top: 80,
              child: Icon(
                Icons.ac_unit,
                color: Colors.white,
              ),
            ),
          ],
        ),
        // 4、ListTitle设置列表,路由列表,Divider分割线
        ListTile(
          title: Text('demo'),
          subtitle: Text('小标题'),
          leading: Icon(Icons.access_alarms),
          trailing: Icon(Icons.ios_share),
          onTap: () => {print('demo跳转')},
        ),
        Divider(
          color: Colors.orange,
          height: 5,
        ),
        ListTile(
          title: Text('test'),
          subtitle: Text('下标题'),
          leading: Icon(Icons.access_alarms),
          trailing: Icon(Icons.arrow_back_ios),
          onTap: () => {print('test跳转')},
        ),
        Divider(),
        ListTile(
          title: Text('ceshi'),
          subtitle: Text('ceshi小标题'),
          leading: Icon(Icons.access_alarms),
          trailing: Icon(Icons.arrow_back_ios),
          onTap: () => {print('ceshi跳转')},
        ),
        // 5、Chip tag部件 avatar设置tag前面的样式,onDeleted增加删除操作
        Chip(
          label: Text('选我'),
          backgroundColor: Colors.orange,
          avatar: CircleAvatar(
            backgroundColor: Colors.pink,
            child: Text(
              'A',
              style: TextStyle(
                color: Colors.black,
              ),
            ),
          ),
          onDeleted: () => {print('删除')},
        )
      ],
    );
  }
}

 7、input输入框、密码框、如何动态获取输入框内的数据:使用有状态组件StatefulWidget,设置值使用setState(()=>{})。input的监听使用onChanged,确认按钮手机上键盘搜索和确定(完成)同样可以触发示例代码如下

这里使用到了有状态组件StatefulWidget,主要是为了输入框内的数据,进行一些数据操作,而StatelessWidget是无状态的组件,里面的数据都是固定不变的

import 'package:flutter/material.dart';

// input输入框、密码框、如何动态获取输入框内的数据:使用有状态组件StatefulWidget,设置值使用setState(()=>{})
class Input extends StatefulWidget {
  @override
  _InputState createState() => _InputState();
}

class _InputState extends State<Input> {
  String username;
  String password;

  login() {
    print(username);
    print(password);
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(25),
      child: Column(
        children: [
          // TextField(
          //   decoration: InputDecoration(
          //     icon: Icon(Icons.verified_user),
          //     labelText: '用户名',
          //     hintText: '请输入用户名',
          //     filled: true,
          //     fillColor: Colors.orange[100],
          //     border: InputBorder.none,
          //   ),
          //   onChanged: (value) => {
          //     print(value),
          //   },
          //   // onSubmitted作用:手机键盘上的完成/搜索的触发条件
          //   onSubmitted: (value) => {
          //     print(value),
          //   },
          // ),
          // Divider(
          //   color: Colors.orange,
          // ),
          TextField(
            keyboardType: TextInputType.phone,
            decoration: InputDecoration(
              prefixIcon: Icon(
                Icons.mobile_screen_share,
                color: Colors.grey,
              ),
              focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.black38),
              ),
              labelText: '手机号',
              hintText: '请输入手机号',
              hintStyle: TextStyle(
                color: Colors.black87,
                fontSize: 12,
              ),
            ),
            onChanged: (value) => {
              setState(
                () => {username = value},
              )
            },
          ),
          TextField(
            obscureText: true, // 输入的内容保密
            keyboardType: TextInputType.text,
            decoration: InputDecoration(
              prefixIcon: Icon(
                Icons.code,
                color: Colors.grey,
              ),
              focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.black38),
              ),
              labelText: '密码',
              hintText: '请输入密码',
              hintStyle: TextStyle(
                color: Colors.black87,
                fontSize: 12,
              ),
            ),
            onChanged: (value) => {
              setState(
                () => {password = value},
              )
            },
          ),
          SizedBox(
            height: 25,
          ),
          Container(
            width: double.infinity,
            child: RaisedButton(
              color: Colors.blue[300],
              child: Text(
                '登录',
                style: TextStyle(color: Colors.white),
              ),
              onPressed: () => {
                login(),
              },
            ),
          )
        ],
      ),
    );
  }
}

 8、按钮:示例如下:

// 按钮的部件:floatingActionButton浮动按钮,浮动在最顶层的按钮通过floatingActionButtonLocation可以随意设置位置;FlatButton文字按钮,点击文字可以触发点击事件;FlatButton.icon只是设置了图标,其他和文字按钮一样

// RaisedButton带溅墨效果的按钮,溅墨的属性splashColor,RaisedButton.icon带图标的溅墨效果按钮,只是带图标,别的和RaisedButton一样;

// OutlineButton带边框的按钮,同样带溅墨效果, OutlineButton.icon带图标的边框按钮,和 OutlineButton一样

import 'package:flutter/material.dart';

// 按钮的部件:floatingActionButton浮动按钮,浮动在最顶层的按钮通过floatingActionButtonLocation可以随意设置位置;FlatButton文字按钮,点击文字可以触发点击事件;FlatButton.icon只是设置了图标,其他和文字按钮一样
// RaisedButton带溅墨效果的按钮,溅墨的属性splashColor,RaisedButton.icon带图标的溅墨效果按钮,只是带图标,别的和RaisedButton一样;
// OutlineButton带边框的按钮,同样带溅墨效果, OutlineButton.icon带图标的边框按钮,和 OutlineButton一样

Widget floatButton(context) {
  return FloatingActionButton(
    child: Icon(Icons.arrow_back),
    elevation: 0,
    backgroundColor: Colors.pink,
    onPressed: () => {
      print('按下浮动按钮'),
      Navigator.pop(context),
    },
  );
}

class ButtonG extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('更多按钮'),
      ),
      body: Container(
        child: Column(
          children: [
            FlatButton(
              onPressed: () => {
                print('按下文字按钮'),
              },
              child: Text('文字按钮'),
            ),
            // 带图标的文字按钮
            FlatButton.icon(
              onPressed: () => {
                print('带图标的文字按钮'),
              },
              icon: Icon(Icons.ac_unit),
              textColor: Colors.blue,
              label: Text('带图标的文字按钮'),
            ),
            // 带效果的按钮
            RaisedButton(
              onPressed: () => {
                print('溅墨效果按钮'),
              },
              child: Text(
                '溅墨按钮',
                style: TextStyle(color: Colors.white),
              ),
              elevation: 0,
              color: Colors.pink,
              splashColor: Colors.orange, //溅墨的颜色
            ),
            // 带图标的效果按钮
            RaisedButton.icon(
              elevation: 0,
              onPressed: () => {
                print('带图标的溅墨按钮'),
              },
              icon: Icon(Icons.access_alarm),
              label: Text('带图标的溅墨按钮'),
              splashColor: Colors.blue,
            ),
            // 带边框的按钮(同样具有溅墨效果)
            OutlineButton(
              onPressed: () => {
                print('带边框的按钮'),
              },
              child: Text(
                '带边框的按钮',
                style: TextStyle(color: Colors.yellow),
              ),
              borderSide: BorderSide(color: Colors.amberAccent),
              splashColor: Colors.black,
            ),
            // 带图标的带边框的按钮
            OutlineButton.icon(
              onPressed: () => {print('带图标的带边框的按钮')},
              icon: Icon(Icons.radio),
              label: Text('带图标的边框按钮'),
              splashColor: Colors.blue,
              borderSide: BorderSide(color: Colors.black),
            ),
          ],
        ),
      ),
      floatingActionButton: floatButton(context),
      floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
    );
  }
}

三、Flutter界面

1、MaterialApp 界面

MaterialApp构成

  • MaterialApp 代表使用纸墨设计(Material Design)风格的应用。里面包含了纸墨设计风格应用所需要的基本控件。

  • title : 在任务管理窗口中所显示的应用名字,这个 Title 是用来定义任务管理窗口界面所看到应用名字的。在原生 Android 系统中点击圆圈 Home 按钮右边的方块按钮就会打开多任务切换窗口。

  • home : 应用默认所显示的界面 Widget,用来定义当前应用打开的时候,所显示的界面。

MaterialApp(
	title: 'Flutter Tutorial',// 指明了这个控件的标题
	home: Scaffold( // 指明了这个控件的主体
		appBar: AppBar(),
		body:
	),
)
import 'package:flutter/material.dart';
import 'package:vscode_flutter/tab.dart';
// import 'package:vscode_flutter/home.dart';

// Material.dart 是基础包,几乎所有的页面都会引入

void main(List<String> args) {
  runApp(App());
}

// 组件套组件
// StatelessWidget 是无状态控件
class App extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter',
      home: TabTest(),
      // home: Home(),
      debugShowCheckedModeBanner: false, // 控制右上角的debug图标
    );
  }
}

2. 顶部工具栏和功能按钮,示例如下

  • leading 部件

    • 创建一个menu部件

    • 使用Icon部件,以及预置图标

  • actions 部件

    • 创建一组actions动作

    • 使用小图标

import 'package:flutter/material.dart';
import 'package:vscode_flutter/drawerList.dart';
// import 'package:vscode_flutter/widgetTest.dart';
import 'package:vscode_flutter/pageTest.dart';

// 提取Scaffold为组件
class TabTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3, //包含了tabs的三个
      child: Scaffold(
        //Scaffold是一个脚手架
        // appBar是一个组件
        appBar: AppBar(
          title: Text('Tab标签切换'),
          elevation: 0, //设置tabBar的阴影,标题下方的阴影
          leading: Icon(Icons.menu), //头部左边的图标
          actions: [
            Icon(Icons.search),
            // Icon(Icons.send),
            // Icon(Icons.verified_user)
          ], //头部右边的图标,可以设置多个
          bottom: TabBar(
            // tab内的文字样式我们可以通过label进行设置
            labelColor: Colors.white,
            labelStyle: TextStyle(
              fontSize: 22,
            ),
            unselectedLabelColor: Colors.black,
            unselectedLabelStyle: TextStyle(
              fontSize: 14,
            ),
            // indicatorColor设置当前选中的标签的下划线的颜色
            indicatorColor: Colors.orange,
            //indicatorWeight设置当前选中的标签的下划线粗细
            indicatorWeight: 2,
            //indicatorSize:TabBarIndicatorSize.label使下换线和文字保持等宽
            //indicatorSize:TabBarIndicatorSize.tab保持默认
            indicatorSize: TabBarIndicatorSize.label,
            tabs: [
              Tab(
                text: '首页',
              ),
              Tab(
                text: '收益',
              ),
              Tab(
                text: '我的',
              ),
            ],
          ),
        ),
        // TabBarView 是和上面Tabs里面的tab一一对应的
        body: TabBarView(
          children: [
            PageTest(),
            Icon(
              Icons.close,
              size: 60,
            ),
            Icon(
              Icons.architecture,
              size: 60,
            ),
          ],
        ),
        drawer: DrawerList(), //设置app的侧边栏
      ),
    );
  }
}

3、侧边栏 Drawer示例如下:

drawer: Drawer( //边栏插件
  child: ListView( //构建列表
    children: <Widget>[ //列表项
      DrawerHeader( //边栏头部
        child: Text('头部'), //头部文字
        decoration: BoxDecoration( //头部装饰
          color: Colors.blue, //背景颜色
        ),
      ),
      ListTile( //列表项
        title: Text( //列表项标题
          '列表', //列表项文字
          textAlign: TextAlign.right, //文字对齐方式
        ),
        trailing: Icon(Icons.message), //列表小图标
        onTap: () {}, //点击动作
      ),
    ],
  ),
),
import 'package:flutter/material.dart';

// 设置app侧边栏、ListView
class DrawerList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        //使页面可以上下滚动
        // EdgeInsets.all(0.0)设置所有的方向都为0
        // EdgeInsets.only(top:5.0) 设置顶部距离5像素 其他方向类似
        padding: EdgeInsets.all(0.0), //去除顶部的留白
        children: [
          DrawerHeader(
            //设置侧边栏的头部
            decoration: BoxDecoration(
              color: Colors.blue, // 设置头部的背景颜色
            ),
            child: Center(
              child: Text(
                'Flutter',
                style: TextStyle(
                  fontSize: 24,
                  color: Colors.white,
                ),
              ),
            ),
          ),
          ListTile(
            title: Text('我的'),
            leading: Icon(Icons.supervised_user_circle),
            trailing: Icon(Icons.arrow_forward_ios), //列表后面的小图标
          ),
          ListTile(
            title: Text('安全'),
            leading: Icon(Icons.group),
            trailing: Icon(Icons.arrow_forward_ios), //列表后面的小图标
          ),
          ListTile(
            title: Text('常见问题'),
            leading: Icon(Icons.settings),
            trailing: Icon(Icons.arrow_forward_ios), //列表后面的小图标
          ),
        ],
      ),
    );
  }
}

四、选项卡Tab布局,示例如下

1. Tab选项卡布局

  • DefaultTabController 标签控制器组件

  • TabBar 标签栏组件

  • TabBarView 标签内容组件

2. 添加标签控制器

  • DefaultTabController

    • length 定义标签个数

    • 定义一个 Scaffold标准布局

    • 定义一个 appBar 头部栏

    • 定义一个 bottom

3. 添加标签栏

  • 添加一组标签栏组件

  • 每个组件都是Tab类型

4. 添加标签栏内容

  • 添加一组标签栏内容组件

5. 自定义标签栏的样式

  • 标签边距

  • 下划线长度

  • 下划线粗细

  • 下划线颜色

  • 标签颜色

  • 未选择状态的颜色

import 'package:flutter/material.dart';
import 'package:vscode_flutter/drawerList.dart';
// import 'package:vscode_flutter/widgetTest.dart';
import 'package:vscode_flutter/pageTest.dart';

// 提取Scaffold为组件
class TabTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3, //包含了tabs的三个
      child: Scaffold(
        //Scaffold是一个脚手架
        // appBar是一个组件
        appBar: AppBar(
          title: Text('Tab标签切换'),
          elevation: 0, //设置tabBar的阴影,标题下方的阴影
          leading: Icon(Icons.menu), //头部左边的图标
          actions: [
            Icon(Icons.search),
            // Icon(Icons.send),
            // Icon(Icons.verified_user)
          ], //头部右边的图标,可以设置多个
          bottom: TabBar(
            // tab内的文字样式我们可以通过label进行设置
            labelColor: Colors.white,
            labelStyle: TextStyle(
              fontSize: 22,
            ),
            unselectedLabelColor: Colors.black,
            unselectedLabelStyle: TextStyle(
              fontSize: 14,
            ),
            // indicatorColor设置当前选中的标签的下划线的颜色
            indicatorColor: Colors.orange,
            //indicatorWeight设置当前选中的标签的下划线粗细
            indicatorWeight: 2,
            //indicatorSize:TabBarIndicatorSize.label使下换线和文字保持等宽
            //indicatorSize:TabBarIndicatorSize.tab保持默认
            indicatorSize: TabBarIndicatorSize.label,
            tabs: [
              Tab(
                text: '首页',
              ),
              Tab(
                text: '收益',
              ),
              Tab(
                text: '我的',
              ),
            ],
          ),
        ),
        // TabBarView 是和上面Tabs里面的tab一一对应的
        body: TabBarView(
          children: [
            PageTest(),
            Icon(
              Icons.close,
              size: 60,
            ),
            Icon(
              Icons.architecture,
              size: 60,
            ),
          ],
        ),
        drawer: DrawerList(), //设置app的侧边栏
      ),
    );
  }
}

六、利用上面的知识实现一个小案例,其中如果要引入图片记得在根目录下pubspec.yaml这个文件在里面配置assets

import 'package:flutter/material.dart';

class PageTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        //图片:如果要配置图片需要找到根目录下pubspec.yaml这个文件在里面配置assets
        Image.asset(
          'images/pic.jpg',
          height: 210,
          fit: BoxFit.fill, //全图显示相当于cover
        ), //引入图片
        //标题
        Padding(
          //Padding组件就是为了有些组件无法设置内边距提供的一个专门设置内边距的组件
          padding: EdgeInsets.all(20),
          child: Row(
            // 在Row中不可以设置padding,没有这个属性,此时如果想加内边距,我们可以使用Padding组件进行设置
            children: [
              // Expanded作用:一行有别的元素,如果当内容超过了自己的宽度,影响了一行内别的元素展示,使用Expanded包裹,可以减去被影响的元素的宽度只在自己的元素内展示
              Expanded(
                child: Column(
                  //两行标题
                  // 在Column中不可以设置padding,没有这个属性
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      '他强任他强,清风拂山岗',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                      ),
                      maxLines: 1,
                    ),
                    // 让上下两个元素间隔大点,使用SizeBox,这是一个空组件,如果是左右就用width
                    SizedBox(
                      height: 5,
                    ),
                    Text(
                      '他横任他横',
                      style: TextStyle(
                        color: Colors.grey,
                      ),
                      maxLines: 1,
                    ),
                  ],
                ),
              ),

              //收藏
              Icon(
                Icons.star,
                color: Colors.red,
              ),
              Text('32'),
            ],
          ),
        ),
        //按钮
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            PubIcon(Icons.phone, 'Phone'),
            PubIcon(Icons.router, 'Rpoter'),
            PubIcon(Icons.share, 'Share'),
          ],
        ),
        //长文字
        Padding(
          padding: EdgeInsets.all(20),
          child: Text(
              'Ea reprehenderit adipisicing consequat tempor nisi. Exercitation sunt duis consequat ipsum proident nisi nulla aliqua veniam minim. Id in labore eiusmod enim velit.'),
        )
      ],
    );
  }
}

class PubIcon extends StatelessWidget {
  final String text;
  final IconData icon;

  PubIcon(this.icon, this.text);
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Icon(
          icon,
          color: Colors.blue,
        ),
        SizedBox(
          height: 5,
        ),
        Text(
          text,
          style: TextStyle(color: Colors.blue),
        )
      ],
    );
  }
}

七、路由Navigator

1、路由的跳转和返回:跳转:就将需要跳转的路由放在最上方,返回:就将当前页面的路由删除

Navigator.push方法是向路由堆中添加一个新的路由;MaterialPageRoute的build方法返回一个新的组件并跳转

import 'package:flutter/material.dart';
// import 'package:vscode_flutter/button.dart';
import 'package:vscode_flutter/widgetTest.dart';

// 路由跳转Navigator
class RouterTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('路由'),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.arrow_back_ios),
        onPressed: () => {
          // 路由跳转
          // print('跳转'),
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => WidgetTestRichText(),
            ),
          ),
          // Navigator.pushNamed(context, '/tab')
        },
      ),
    );
  }
}

Navigator.pop方法是从路由堆里面拿出来最前面的路由。路由使用context参数传入

Navigator.pop(context),

2、初始路由,可以在MaterialApp中初始化一些路由。使用routes进行路由路径映射设置,使用initialRoute设置初始化路径,此时需要去掉home的属性

import 'package:flutter/material.dart';
import 'package:vscode_flutter/button.dart';
import 'package:vscode_flutter/hello.dart';
import 'package:vscode_flutter/input.dart';
import 'package:vscode_flutter/pageTest.dart';
import 'package:vscode_flutter/router.dart';
import 'package:vscode_flutter/tab.dart';
// import 'package:vscode_flutter/home.dart';

// Material.dart 是基础包,几乎所有的页面都会引入

void main(List<String> args) {
  runApp(App());
}

// 组件套组件
// StatelessWidget 是无状态控件
class App extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter',
      // home: RouterTest(),
      // home: ButtonG(),
      // home: TabTest(),
      // home: Home(),
      debugShowCheckedModeBanner: false, // 控制右上角的debug图标
      initialRoute: '/',
      routes: {
        '/': (context) => RouterTest(),
        '/hello': (context) => Hello(),
        '/tab': (context) => TabTest(),
        '/button': (context) => ButtonG(),
      },
    );
  }
}

3、跳转带名字的路由

使用Navigator.pushNamed跳转到一个带名字的路由('/tab'是在MaterialApp中定义的路由映射路径)

Navigator.pushNamed(context, '/tab')

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上登堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值