Flutter学习第六天 基础组件Text Button Image

这个转自我自己的有道云 想看图片去那里

文档:Day3_4 flutter基本组件.md
链接:http://note.youdao.com/noteshare?id=e40beb1b7bd450bb669a80f7251ec646&sub=F079DA91890B4FA49DE86011DEEEB120

flutter基本组件

历史遗留问题

  • didUpdateWidget在什么时候调用
  • 同时会将一个快捷键
  • 还有就是之前的时候我们在Material的home中放StatefulWidget其实是可以的, 但是我们要将它重启
  • 还有就是我们有些时候可能想要将一个StatelessWidget转化成一个StatefulWidget 这个时候我们可以使用快捷键 alt + enter

上节课我们没有介绍这个didUpdateWidget 方法什么时候调用的, 所以我们需要知道这个回调是什么时候调用的

  • 还有就是一个抽取的快捷键 这个可以将我们的Widget单独抽取到一个类里面(默认的是)
  • 现在用的是ctrl + alt + 1 本来因该是ctrl + alt + w (但是我把按键改了) 这个快捷键名称叫extract

快捷键可以在setting里面改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pjpf8XWb-1583671032326)(1AC7926D69154DE0B681707FE2D45EEA)]

上节课我们没有介绍这个didUpdateWidget

之前的生命周期之所以有问题主要是

我们可以来到官方文档来

点到Widget 然后再点State

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7gcTb1A7-1583671032330)(52A69C3F4C394161BBA6828FB0C786DB)]

就可以看到对应的对这个didUpdateWidget的描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dGzFXd7I-1583671032331)(576849C3F5824BD683BE7CFF5218E2CB)]

大概就是当父组件重新build的时候就会调用这个方法,改变这个树中的位置,去更新了一个新的Widget的时候就会调用这个方法

  • 这里因为我们调用了setState就会重新调用build
  • 而这个HYHomeContent而这个HYHomeContent()处于这个build函数它是一个临时变量(闭包)
  • 当我们重新调用这个build函数的时候它也被重新调用了

所以总结来说这个方法要被调用需要两个条件

  • 父组件的build方法被重新调用
  • 而子组件被重新创建

同时这里还有一种理解 State里面不是有一个指向StatefulWidget的指针_widget 当父组件build之后它肯定不是原来的地址所以这个指针也一定会变换 这个时候重建子组件 这个函数就会被调用

import "package:flutter/material.dart";

main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
//     MaterialApp home不能是StatefulWidget 其实是可以的
//    将StatelessWidget转化成StatefulWidget alt + enter
        home: HYDemo()
    );
  }
}

class HYDemo extends StatefulWidget {
  @override
  _HYDemoState createState() => _HYDemoState();
}

class _HYDemoState extends State<HYDemo> {

  _HYDemoState() {
    print("_HYDemoState 构造函数打印");
  }

  @override
  void initState() {
    // TODO: implement initState
    print("_HYDemoState initState函数调用");
    super.initState();
  }

  @override
  void didUpdateWidget(HYDemo oldWidget) {
    // TODO: implement didUpdateWidget
    print("_HYDemoState didUpdateWidget被调用");
    super.didUpdateWidget(oldWidget);
  }

  @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("StatefulWidget的生命周期函数")
      ),
      body: Column(
        children: <Widget>[
          HYHomeContent()
        ],
      ),
      floatingActionButton: RaisedButton(
        child: Icon(Icons.add),
        onPressed: () {
          setState(( ) {});
        },
      ),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRSFHFZW-1583671032332)(47D6DA1933D44E329D22C4A1DFBCB71E)]

这个地方注它是要更新(重新调用build方法)一个新的Widget, 也就是说它需要重新创建一个子的Widget

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AETij7HF-1583671032334)(3467625EA2F047C89743ACC144901A80)]

之前我们的这中做法我们是在这个地方插入了一个Widget但是我们并没有build创建这个Widget

编程范式

这里我们来说一下编程范式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HSRvX9rS-1583671032335)(D031392E01DB4C2181336CE570EB00BA)]

  • 编程范式有两种一个是命令式编程
  • 命令式编程 就是一步一步的写命令 要计算机做什么就写什么
  • 声明式编程 通常是描述目标的性质, 你因该是什么样的, 依赖哪些状态,并且当状态发生改变的时候, 我们通过某些方式通知目标发生变化

这样看肯定不好理解但是我们可以这样理解

假如说我们要开发一个界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ulk7e1mh-1583671032336)(A49E0FDEEB584C50B27EA0CE800693B5)]

如果是命令式编程
  1. 创建 + button, 并且设置 + 按钮的位置 Rect: x/y/width/height
  2. 创建 - button, Rect: x/y/width/height
  3. label Rect
  4. 监听 + -

方法:
5. 获取label标签
6. 设置最新的值

如果是声明式编程

各大公司基本 苹果 -》 SwiftUI,Google -》Flutter , 所以大前端以后的趋势因该是声明式编程会偏多

为什么要用声明式编程因为这样写起来简单, 而且它的逻辑更清晰

  • 一般来说声明式编程是依赖一些框架的 vue/react/flutter
  • 一般是设置它的配置信息 到底是怎么分布是让框架帮我们来做的
  • 下面的这个我们这个东西一开始垂直排布的 所以它的第一个是Column
  • 然后里面的东西是Row
    Column(
        children: [
            Row(
                children: [
                    Button(),
                    Button(),
                ]
            ),
            Text()
        ]    
    )

当我们声明之后它就知道, 哦哦这里你需要垂直排布,children里面这些东西就是垂直排布的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0deUvbYg-1583671032337)(1F400541E58D4AD097A19F1440A5CB56)]

  • 同时里面的数据也是 声明式的
  • 我们可以在某个地方写好数据 让后给他说清楚这个地方是放这个数据
  • 我们只需要将数据挂载上去然后在对应的地方刷新页面就可以了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NLNY0eGi-1583671032339)(369AF9C5FD834B36981E9175613C3D50)]

这种一步一步的模式就是命令式编程

我们的前端的声明式和命令式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RwInRlky-1583671032340)(5DCFCE36D74842D2B2DFE94D699E9A78)]

flutter的基本组件

这里我们主要讲三个

  • Text
  • Button
  • Image

Text(文本显示组件)

这个就是这个东西最基础的用法

import "package:flutter/material.dart";

main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HYHomePage()
    );
  }
}

class HYHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("文本的使用"),
      ),
      body: HYHomeContent()
    );
  }
}

class HYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(
      "hello world"
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zUuKEaB0-1583671032341)(2D0BBBFDBF8B445A956C220C16266454)]

这个东西使用还是很简单的, 但是还是必须要知道 这些数据不知道的时候直接点进去看一下就可以了

class HYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(
      "hello world, ,hello worldhello worldhello world\nhello world\n\nhello world",
      style: TextStyle(
          fontSize: 30,
          color: Colors.red,
          fontWeight: FontWeight.bold
      ),
      textAlign: TextAlign.center,
      maxLines: 1,
//      超出单行的文字隐藏
      overflow: TextOverflow.ellipsis,
      textScaleFactor: 1.5,
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWtIfd24-1583671032343)(E2284BA21DFE489CBC22FDCCBF441D33)]

我们这个时候我们可以使用ctrl + alt + 1(w) 来单独抽取出来Widget创建一个类

class TextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
//    Text 并不是最终渲染的Widget Text 并不是RanderText
    return Text(
      "helle world\nhello flutterhello flutterhello flutterhello flutterhello flutter\nhello flutterhello flutter",
//        但是不能居中
//        因为宽度只是包裹内容 并没有充满整行
//    但是
      textAlign: TextAlign.center,
      maxLines: 2,
//        最大行数 默认是需要占几行就是几行
      overflow: TextOverflow.ellipsis,
//        缩放文本
      textScaleFactor: 1.5,
      style: TextStyle(
          fontSize: 30,
          color: Colors.red,
//          字体
//          这里可以使用第三方字体
//          fontFamily:
          fontWeight: FontWeight.bold
      ),
    );
  }
}

这里还有一个问题就是如果我们像之前一样直接

main() {
    runApp(Text("test"));
}

这样它就会报错,但是它报的错并不是Text而是RichText

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1CcT5qqB-1583671032344)(F98671CBBE9F40E19B3FA61813661002)]

这是为什呢

因为我们这里实际上进行渲染的不是Text Widget而是其他的Widget

  • 首先我们需要知道我们创建了一个Widget 但是它渲染的是这个TextDemo吗
  • 不是它渲染你的是build里面的东西
class TextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
//    Text 并不是最终渲染的Widget Text 并不是RanderText
    return Text(
      "helle world\nhello flutterhello flutterhello flutterhello flutterhello flutter\nhello flutterhello flutter",
//        但是不能居中
//        因为宽度只是包裹内容 并没有充满整行
//    但是
      textAlign: TextAlign.center,
      ),
    );
  }
}

那Text真正渲染的Widget又是哪个呢

  • 我们就只能点进去看Text的build是用什么进行渲染的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-edCY6lBh-1583671032346)(910AB23C7D354AB9ABD0B5503016AB24)]

可以看到它是用的RichText进行渲染的

当你最后再点进去看到这个的时候它就是最终进行渲染的Widget

它就是最后的Widget

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cvDFB3hr-1583671032347)(B061FB76F5A940629DD2C8296238FC1B)]

富文本(Text.rich)
  • 首先什么是富文本呢 富文本就是文字中有不同的样式的文本

但是如果你想做一个富文本的话就不能使用Text Widget了

我们可以使用Text.rich产生富文

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-21AfmWHa-1583671032348)(853F695023584927AE172115ADD6557F)]

源码里面要求我们传一个

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FoHaBkGg-1583671032349)(065D1D76431946D08F6FB6016A233825)]

但是这个东西是一个抽象类 所以我们ctrl + alt + B 看实现类 我们通常会使用TextSpan 来实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rqcWdvhi-1583671032350)(95FBEAA2DC4940E38A2EF2EDEF7DC397)]

class HYHomeContent extends StatefulWidget {
  @override
  _HYHomeContentState createState() => _HYHomeContentState();
}

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Text.rich(
      TextSpan(
        
      )
    );
  }
}

所以我们来看

class HYHomeContent extends StatefulWidget {
  @override
  _HYHomeContentState createState() => _HYHomeContentState();
}

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Text.rich(
      TextSpan(
        text: "Hello world",
        style: TextStyle(color: Colors.red)
      )
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lk5njZuY-1583671032351)(38CF090D666346CCBECBC68B06814E49)]

但是如果我们想要一个一颜色然后中间插入子图图标啥的 我们就可以 使用children

然后让它TextSpan 嵌套TextSpan然后来实现对应的操作

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Text.rich(
      TextSpan(
        children: [
          TextSpan(
            text: "Hello world",
            style: TextStyle(color: Colors.red)
          ),
          TextSpan(
              text: "Hello world",
              style: TextStyle(color: Colors.blue)
          ),
          TextSpan(
//            这里使用了字体图标
              text: "\ue577",
              style: TextStyle(color: Colors.red, fontFamily: 'MaterialIcons')
          )
        ]
      )
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JW6xYBWm-1583671032352)(A13B1C1744034654A87FE369F85C077E)]

按钮组件

按钮组件可以说看起来是基本都是由FlatButton衍生出来的

所以也没有生好看的 讲代码打一遍出来

  1. RaisedButton Raised突起
  2. FlatButton Flat 平坦的
  3. OutlineButton增加边框
  4. FloatingActionButton 会在整个屏幕的右下出现按钮
  5. 自定义Button 其实就是用FlatButton来做自定义(因为这个东西最简单)
  • 同时注意啊 我们这个是没有 width height这些属性的 这些东西不是通过这个东西调整的
RaisedButton
class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text("RaisedButton", style: TextStyle(fontSize: 20)),
      textColor: Colors.red,
      color: Colors.purple,
      onPressed: () {
        print("RaisedButton");
      },
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f5azNZAu-1583671032353)(D830CE722BE346C5AC04E63565C48C25)]

  • 注意: 必传参数和@required 的区别 必传参数
    • 必传参数如果不传编译器都会直接报错
    • @require 如果不传编译也可以通过 但是会有警告

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yjaf3bbX-1583671032354)(0AF7852C04094AE8A20637FE0E32F7DB)]

FlatButton
class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return FlatButton(
      child: Text("FlatButton"),
      onPressed: () {},
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3brsVKn4-1583671032355)(7E4751C7E1894034B07C638FF69CC134)]

这个就是最基础的FlatButton 组件 你给它加一下东西以后也就可以变成其他的button的样子所以说这个东西算是最基础的button

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        FlatButton(
          child: Text("FlatButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        RaisedButton(
          child: Text("RaisedButton"),
          color: Colors.orange,
          onPressed: () {},
        )
      ],
    );
   }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GW6MMUlB-1583671032356)(DF70B1BDBC664465866D43332F14BEA2)]

我们可以看到这个如果改了颜色都差不多

我们来看看源码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dm8VT6Ya-1583671032357)(23C417AEC4AE49A889A5F08F9CF559B5)]

他们继承的都是同一个父类所以不难想象 RaisedButton可能就是比正常的多了一个 color默认值之类的东西

OutlineButton

就是说它设置了一些轮廓, 它也还有一些自己的属性, 这些东西自己看一下就可以了

相对来说用的不多

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return OutlineButton(
      child: Text("Test"),
      onPressed: () {},
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p3mMn6b6-1583671032358)(27C56D0A9D3D4309BEFF6B6AE282A3D1)]

floatingActionButton

这个是固定在屏幕右下角的按钮

class HYHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Button")
      ),
      body: HYHomeContent(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {},
      ),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gdRhNf9z-1583671032359)(A99867811B2A43AE969A05F7E8FF2E95)]

同样我们也可以设置这个按钮的位置

class HYHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Button")
      ),
      body: HYHomeContent(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {},
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4Ptq0sr-1583671032361)(AB6DA10C046545D1A718EBF7D90CCF53)]

自定义组件
class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        FlatButton(
          child: Text("FlatButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        RaisedButton(
          child: Text("RaisedButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        OutlineButton(
          child: Text("OutlineButton"),
          onPressed: () {},
        ),
        FlatButton(
          child: Row(
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),
      ],
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EEqEV2Fd-1583671032363)(06C7256BEB63433AB11CCDEC38E8514E)]

  • 然后这里有个问题 我们这里本来没有这个按钮的时 这些按钮是没有居中的但是现在居中了
class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        FlatButton(
          child: Text("FlatButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        RaisedButton(
          child: Text("RaisedButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        OutlineButton(
          child: Text("OutlineButton"),
          onPressed: () {},
        ),
//        FlatButton(
          color: Colors.amberAccent,
//          child: Row(
//            children: <Widget>[
//              Icon(Icons.favorite, color: Colors.red),
//              Text("喜欢作者")
//            ],
//          ),
//          onPressed: () {},
//        ),
      ],
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4qcoEmjQ-1583671032365)(A71FC626D4444804B72D191104FCCBB1)]

  • 这是为什么呢

我们给它一个背景颜色 发现它是占据了一行的

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        FlatButton(
          child: Text("FlatButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        RaisedButton(
          child: Text("RaisedButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        OutlineButton(
          child: Text("OutlineButton"),
          onPressed: () {},
        ),
        FlatButton(
          color: Colors.amberAccent,
          child: Row(
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),
      ],
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3hl4PyGn-1583671032366)(86A8949A842E48E78F8D530C7390F990)]

  • 前面的那些按钮整体来说是包裹文字的
  • 但是为什么这个东西占据了一行呢

但是注意这个东西是没有width属性的, 所以我们不能给他设置宽度 这个不能按原来的设计思路

这个其实是Container这些组件可以让它的子组件 撑满它自己的作用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIhlvKIT-1583671032367)(47ACE4C4516241A79517521001453537)]

如果我们这里也想要这样的话我们可以通过设置主轴对齐方式来完成

        FlatButton(
          color: Colors.amberAccent,
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VGXdnViU-1583671032368)(1D37E55F67884D75806881EFDAEDED6B)]

这样就又回来了

但是为什么我们下面的这个宽度会和上面的对其方式有关呢

  • 这是因为Column的交叉轴轴对其方式默认是居中的居中的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cruLt3a9-1583671032369)(2FE350542CA44FCCB5999AB9DFAEFEE0)]

如果要改我们也可以该它的交叉轴对齐方式来改变这个东西

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: <Widget>[
        FlatButton(
          child: Text("FlatButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        RaisedButton(
          child: Text("RaisedButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        OutlineButton(
          child: Text("OutlineButton"),
          onPressed: () {},
        ),
        FlatButton(
          color: Colors.amberAccent,
          child: Row(
//            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),
      ],
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sz0SfRhi-1583671032370)(30311A4923AB4D44B9A2B7C9A1D57996)]

但是布局我们现在不讲

后面再讲

所以我们现在就这样

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Column(
//      crossAxisAlignment: CrossAxisAlignment.end,
      children: <Widget>[
        FlatButton(
          child: Text("FlatButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        RaisedButton(
          child: Text("RaisedButton"),
          color: Colors.orange,
          onPressed: () {},
        ),
        OutlineButton(
          child: Text("OutlineButton"),
          onPressed: () {},
        ),
        FlatButton(
          color: Colors.amberAccent,
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),
      ],
    );
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qeq5DFXP-1583671032371)(285EE652A5BD4CAD866B53A6EF2150FB)]

然后我们现在想要圆角 这个时候我们就可以使用这个Shape

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RAc97aMs-1583671032372)(415378AFBACF4F7293742139F58E7089)]

但是shape又是一个抽象类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uYNfecDr-1583671032373)(881C98834DD342FE832A61E55CEDA249)]

所以我们ctrl + alt + b 来看这个 抽象类的实现类

这里的话我们使用这个 就可以做出一个小的圆角

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6cZgjYWD-1583671032375)(A40D2AAFCB8C47689490224D5863779C)]

        FlatButton(
          color: Colors.amberAccent,
//          这个东西非常重要borderRadius
          shape: RoundedRectangleBorder(
            borderRadius: ,
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),

然后我们看看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWvIASgf-1583671032377)(30D90C3BBF984E3F9692273BBECF7B2F)]

这个all要传一个Radius对象非常麻烦 所以我们选择使用这个 circular 这里里面传进来一个double就行了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r9Wdiy1D-1583671032380)(763E394197A243A696E0513882688BD2)]

但是这里其实还是使用的构造函数的重定向

        FlatButton(
          color: Colors.amberAccent,
//          这个东西非常重要borderRadius
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Icon(Icons.favorite, color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: () {},
        ),

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DjXnbnmU-1583671032381)(17C4B9E1A0BB478EB7C5DE16D8E83872)]

图片也没有什么好说的

图片的基础使用 主要就是围绕这个Image来使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cZjaI0h5-1583671032382)(CEE8001F048E4B9183896B7C8135FA9E)]

  • 网络图片可以这样使用
class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
   }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7OCPiuGi-1583671032384)(8F27E190AEA64C6987324ADC962F2ED1)]

那么我们来看一下这个Image的用法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2C89JdL-1583671032385)(6A2504985F734D78B0CA4ECF66527C57)]

那么来试一下

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image(
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TE4AyjAy-1583671032386)(491D24BFEBA54E958A79B9906633F105)]

那么其他属性可以用吗试一下

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image(
      color: Colors.red[100],
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-voy1xEbx-1583671032388)(9F62E701B6004CB6936D98B9FCF7899E)]

这个color会覆盖掉原来的颜色

它其实做的是一个混入图片的过程, 并不是填充不满的位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aT9dFb1Q-1583671032389)(2391D196BF63428886ECE010998BAB6A)]

图片可以设置它的宽高 如果不满默认是会按比例进行缩放的 自动适应长边

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image(
//      color: Colors.red[100],
      width: 200,
      height: 200,
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVpHfCok-1583671032390)(EC3F595038B84DF0A812806FE92661A9)]

也可以调整它的填充方式 默认就是这个contain

    Image(
//      color: Colors.red[100],
      width: 200,
      height: 200,
      fit: BoxFit.contain, 
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),
    );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vy6yTNlT-1583671032391)(DEC5D557674A44919E22C4CD55A8D63E)]

BoxFix.cover也会按比例缩放不过它适应的是短边

  • BoxFit.fill 会变形 这个会填充整个图片
  • BoxFix.cover显示不完
  • BoxFix.contain默认是不变形的
  • BoxFix.fitWidth适应宽度
  • BoxFix.fitHeight适应高度
    return Image(
//      color: Colors.red[100],
      width: 200,
      height: 200,
      fit: BoxFit.cover,
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),

    );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UsKZkjfA-1583671032392)(0D56632F67244D67BE4E04C4329407D5)]

超过部分重复

    return Image(
//      color: Colors.red[100],
      width: 200,
      height: 200,
      fit: BoxFit.contain,
      repeat: ImageRepeat.repeat,
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),

    );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GfReNda4-1583671032395)(F10BFABE712249379CA4B0877FB2D6FE)]

设置对其方式 alignment

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image(
//      color: Colors.red[100],
      width: 200,
      height: 200,
      fit: BoxFit.contain,
      repeat: ImageRepeat.repeat,
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),
      alignment: Alignment(-1, -1),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lns1srDV-1583671032396)(8A46F98078AD42B2A26E193FBFFA9511)]

另外这个alignment也可以使用 Alignment.topCenter 这种常量值 来设置

我们也可以让颜色混入 不过实际开发中我们不常用这种开发方式

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image(
      color: Colors.red[100],
      colorBlendMode: BlendMode.colorDodge,
      width: 200,
      height: 200,
      fit: BoxFit.contain,
      repeat: ImageRepeat.repeat,
      image: NetworkImage("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg"),
      alignment: Alignment(-1, -1),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tOg6vnvf-1583671032397)(7AFBAEB62AA5495D855EBE178DD4A08D)]

使用本地图片

但是使用前要进行配置

  1. 在根目录下面新建一个assets/images文件夹
  2. 我们找到对应的 pubspec.yaml文件

然后

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M4Cs8Jj8-1583671032398)(0FA0C39C0EB043299AE760EEBA1E2D6B)]

然后重新运行一下或者 最好打开终端然后输入flutter packages get

当我们的pubspec.yaml 配置修改过以后 最好打开终端然后输入flutter packages get

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ttRpAZnU-1583671032399)(C22829AB8B5A4BFC840AF110F7F03FA3)]

class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image.asset("assets/images/test.jpg");
  }
}
class _HYHomeContentState extends State<HYHomeContent> {
  @override
  Widget build(BuildContext context) {
//    return Image.network("https://www.lianaiyx.com/d/file/GalGame/2020-01-04/f8ba6319c3bdf752d391beb51c7dabfd.jpg");
    return Image(
        image: AssetImage("assets/images/test.jpg"),
    );
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UwRYedO7-1583671032399)(2AB9D6F6C5F24F81A2DA3443C76F84C1)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值