[Flutter]flutter基础之组件基础(七)

一、概述

因为很多的基础小部件( Widget ) 依赖于布局 Widget ,所以在本套基础讲解中,会穿插各种 Widget 的说明,并没有按照一定的分组顺序进行讲解。就是用到什么讲解什么,但是力争做到讲解的够清晰。所以现在开始说明一些基础的布局 Widget, 后续很多其他的 Widget 在使用中会依赖于或用到布局的 Widget ,所以在此先进行说明。

二 、Container Widget

容器 Widget ,其是一个可以设置宽高,边距,装饰等的 Widget ,有一个子 Widget 属性 child 。如果没有设置子 Widget ,容器会尽可能大的展示。它继承自 StatelessWidget ,是一个无状态的 Widget 。构造方法如下:

Container({
  Key key,
  //AlignmentGeometry类型可选命名参数,容器内子Widget如何对其,使用其子类Alignment
  this.alignment,
  //EdgeInsetsGeometry类型可选命名参数,设置容器内边距
  this.padding,
  //Color类型可选命名参数,容器填充色
  Color color,
  //Decoration类型可选命名参数,绘制在child子Widget后面的装饰,使用BoxDecoration
  Decoration decoration,
  //Decoration类型可选命名参数,绘制在child子Widget前面的装饰,使用BoxDecoration
  this.foregroundDecoration,
  //double类型可选命名参数,容器的宽度
  double width,
  //double类型可选命名参数,容器的高度
  double height,
  //BoxConstraints类型可选命名参数,对child设置的Widget的约束
  BoxConstraints constraints,
  //EdgeInsetsGeometry类型可选命名参数,设置容器外边距
  this.margin,
  //Matrix4类型可选命名参数,在绘制容器之前要应用的转换矩阵
  this.transform,
  //Widget类型可选命名参数,容器包含的子Widget
  this.child,
})

其中 colordecoration 不能同时设置。

Decoration 是一个抽象类,这里需要使用 BoxDecoration ,是一个用于设置如何绘制盒子的不可变的的描述。盒子的主体是分层绘制的。 最底层是颜色,它填充了框。 在此之上的是渐变,渐变也填充了该框。 最后是图像,其精确对齐由 DecorationImage 类控制。边框涂在身体上,阴影自然在其下方绘制。其构造方法如下:

const BoxDecoration({
  //Color类型可选命名参数,填充背景色
  this.color,
  //DecorationImage类型可选命名参数,在背景或渐变上绘制的图像
  this.image,
  //BoxBorder类型可选命名参数,边框设置
  this.border,
  //BorderRadiusGeometry类型可选命名参数,设置圆角
  this.borderRadius,
  //List<BoxShadow>类型可选命名参数,盒子后面的盒子投射的阴影列表
  this.boxShadow,
  //Gradient类型可选命名参数,填充框时使用的渐变
  this.gradient,
  //BlendMode类型可选命名参数,应用于框的颜色或渐变背景的混合模式
  this.backgroundBlendMode,
  //BoxShape类型可选命名参数,将背景颜色、渐变和图像填充到并作为boxShadow投射的形状
  this.shape = BoxShape.rectangle,
})

Container 基本使用方式如下:

import 'package:flutter/material.dart';

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

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

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(    //Container
        color: Colors.yellow,
      ),
    );
  }
}

此时的 Container 会充满整个屏幕,尽可能大。

其它属性设置

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(              //Container
        width: 300,
        height: 200,
        child: Text("这是一个文本",),
        alignment: Alignment.topCenter,  //子Widget的相对于父级Container的对齐方式
        padding: EdgeInsets.all(20),   //设置内边距,文本的每个边外都有20的边距
        margin: EdgeInsets.all(50),   //设置外边距,Container每个边外有50的外边距
        color: Colors.yellow,    //填充色
        transform: Matrix4.rotationZ(0.2),   //围绕Z轴旋转指定弧度
        foregroundDecoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage("http://www.mwpush.com/uploads/avatar.png"),
            fit: BoxFit.fill
          ),
          border: Border.all(
            width: 5,
            color: Colors.blue
          ),
        ),
      ),
    );
  }
}

效果如下:

20203201145.jpg

foregroundDecoration 用于设置前景装饰效果,所以如果有重叠,当加载图片时会覆盖 Container 本身的内容。如果不希望覆盖,使用背景装饰效果 decoration 即可,使用方式相同,只是使用 decoration 时不能使用 color ,使用如下:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(
        width: 300,
        height: 200,
        child: Text("这是一个文本",),
        alignment: Alignment.topCenter,  //子Widget的相对于父级Container的对齐方式
        padding: EdgeInsets.all(20),   //设置内边距,文本的每个边外都有20的边距
        margin: EdgeInsets.all(50),   //设置外边距,Container每个边外有50的外边距
        transform: Matrix4.rotationZ(0.2),   //围绕Z轴旋转指定弧度
        constraints: BoxConstraints(    //设置最大最小约束
          minHeight: 300,
          minWidth: 300,
          maxHeight: 400,
          maxWidth: 400,
        ),
        decoration: BoxDecoration(      //decoration
          image: DecorationImage(
            image: NetworkImage("http://www.mwpush.com/uploads/avatar.png"),
            fit: BoxFit.fill
          ),
          border: Border.all(
            width: 5,
            color: Colors.blue
          ),
          borderRadius: BorderRadius.all(Radius.circular(10)),  //设置圆角
        ),
      ),
    );
  }
}

效果如下:

2020321827.jpg

BoxDecoration 还可以设置渐变色等属性。

三、Center Widget

Center 是将子 Widget 放置于其中心的 Widget 。如果其宽高没有设置,则其会尽可能大的展示。可通过设置宽度与高度因子来控制大小。比如设置宽度因子后,Center 的宽度值为子 Widget 的宽度乘以宽度因子的值。宽度与高度因子的值必须为正数。其构造方法如下:

const Center({
  Key key, 
  //double类型可选命名参数,宽度因子
  double widthFactor, 
  //double类型可选命名参数,高度因子
  double heightFactor, 
  //Widget类型可选命名参数,要显示的子Widget
  Widget child 
})

使用如下:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(
        color: Colors.yellowAccent,
        child: Center(              //Center
          widthFactor: 2,
          heightFactor: 2,
          child: Container(
            color: Colors.red,
            child: Text("中心文本",),
          ),
        ),
      )
    );
  }
}

这里为了看清显示的效果,使用了 Container Widget 来包裹 CenterCenterchild Widget ,因为 Container 可以设置填充色,便于区分。效果如下:

2020322752.jpg

四、Padding Widget

Padding 是用来设置内填充(内边距)的 Widget ,在 Container 中也可以设置 Containerpadding ,两者并没有区别。Container 是将多个单独的 Widget 进行组合使用,需要时只需设置相应的属性即可。作用是通过设置内边距的大小使其进行膨胀,在其子 Widget 周围创造出一定的空间。其构造函数方法如下:

const Padding({
  Key key,
  //EdgeInsetsGeometry类型必传参数,内边距
  @required this.padding,
  //Widget类型可选命名参数,要显示的Widget
  Widget child,
})

使用方法如下,与上述 Center 实现效果差不多,代码中的 Container 也是为了使效果看的更清晰:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Padding(             //Padding
          padding: EdgeInsets.all(50),
          child: Container(
            color: Colors.red,
            child: Text("Padding"),
          ),
        ),
      ),
    );
  }
}

五、Align Widget

Align 可以设置其子 Widget 相对自己的对齐方式,并可以根据子 Widget 的大小调整其自己的大小。其可以设置宽度和高度因子,如果不设置,则其会尽可能的大的展示,如果设置,比如设置宽度因子,则 Align 的宽度将是其子 Widget 的宽度乘以宽度因子。构造方法如下:

const Align({
  Key key,
  //AlignmentGeometry类型可选命名参数,设置如何对齐,AlignmentGeometry为抽象类,
  //通常使用Alignment或FractionalOffset
  this.alignment = Alignment.center,
  //double类型可选命名参数,宽度因子
  this.widthFactor,
  //double类型可选命名参数,高度因子
  this.heightFactor,
  //Widget类型可选命名参数,要显示的Widget
  Widget child,
})

AlignCenter 类似,不同的是 Align 可以设置其子 Widget 相对于自己的对齐方式,而 Center 则是居中对齐。

Alignment 在此用来设置对其方式,其定义的是一个矩形中的点。其提供了几种对齐方式可以直接使用,如下:

/// The top left corner.
static const Alignment topLeft = Alignment(-1.0, -1.0);
/// The center point along the top edge.
static const Alignment topCenter = Alignment(0.0, -1.0);
/// The top right corner.
static const Alignment topRight = Alignment(1.0, -1.0);
/// The center point along the left edge.
static const Alignment centerLeft = Alignment(-1.0, 0.0);
/// The center point, both horizontally and vertically.
static const Alignment center = Alignment(0.0, 0.0);
/// The center point along the right edge.
static const Alignment centerRight = Alignment(1.0, 0.0);
/// The bottom left corner.
static const Alignment bottomLeft = Alignment(-1.0, 1.0);
/// The center point along the bottom edge.
static const Alignment bottomCenter = Alignment(0.0, 1.0);
/// The bottom right corner.
static const Alignment bottomRight = Alignment(1.0, 1.0);

比较简单,不做中文说明。从其定义可以看出,其定义的方式都是使用 Alignment() 构造方法,如下:

//x,y均为double类型的必传参数,用于定义一个点的x和y轴值
const Alignment(this.x, this.y)

所以可以直接使用构造函数定义需要通过哪个点对齐,如下:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Align(
          child: Container(child: Text("Align"), color: Colors.red,),
          alignment: Alignment(0.2, 0.5),
          widthFactor: 10,
          heightFactor: 10,
        ),
      ),
    );
  }
}

Alignment(0.0, 0.0) 表示矩形的中心点。从 -1.0 到 +1.0 的距离是从矩形的一侧到矩形的另一侧的距离。 因此,水平(或垂直)2.0 个单位等于矩形的宽度(或高度)。Alignment(-1.0, -1.0) 表示矩形的左上方,Alignment(1.0, 1.0) 表示矩形的右下角。Alignment(0.0, 3.0) 表示一个点,该点相对于矩形水平居中,垂直于矩形底部低于矩形的高度。Alignment(0.0, -0.5)表示相对于矩形水平居中且顶部边缘与中心之间垂直居中的点。

以上面的代码为例,其对齐的点的计算方法为( 0.2*Text的宽度/2 + Text的宽度/2, 0.5*Text的高度/2+Text的高度/2 )

Alignment 使用的坐标系,其原点位于容器的中心点。

FractionalOffset 用来定义一个偏移量,其也提供了几个常用的值,如下:

/// The top left corner.
static const FractionalOffset topLeft = FractionalOffset(0.0, 0.0);
/// The center point along the top edge.
static const FractionalOffset topCenter = FractionalOffset(0.5, 0.0);
/// The top right corner.
static const FractionalOffset topRight = FractionalOffset(1.0, 0.0);
/// The center point along the left edge.
static const FractionalOffset centerLeft = FractionalOffset(0.0, 0.5);
/// The center point, both horizontally and vertically.
static const FractionalOffset center = FractionalOffset(0.5, 0.5);
/// The center point along the right edge.
static const FractionalOffset centerRight = FractionalOffset(1.0, 0.5);
/// The bottom left corner.
static const FractionalOffset bottomLeft = FractionalOffset(0.0, 1.0);
/// The center point along the bottom edge.
static const FractionalOffset bottomCenter = FractionalOffset(0.5, 1.0);
/// The bottom right corner.
static const FractionalOffset bottomRight = FractionalOffset(1.0, 1.0);

可以看到,其与 Alignment 类似,不同之处在于 Alignment() 定义的是一个点(计算方法在上面),而 FractionalOffset() 定义的是两个点,这两个点是单独确定的。对于当前 Widget ,这里为 Text ,其点的计算方式为:(0.2*Text的宽度, 0.5*Text的高度) 。对于父级 Widget ,这里为 Container 则是 (0.2*Container的宽度, 0.5*Container的高度) 。最后使两个点重合,即将 Text 的点移动到 Container 定位的点处。使用

FractionalOffset 时,其原点位于容器的左上角。

此外,除了提供 FractionalOffset(double x, double y) 构造方法,另外还提供了如下两个构造方法:

factory FractionalOffset.fromOffsetAndSize(Offset offset, Size size) {
  assert(size != null);
  assert(offset != null);
  return FractionalOffset(
    offset.dx / size.width,
    offset.dy / size.height,
  );
}

factory FractionalOffset.fromOffsetAndRect(Offset offset, Rect rect) {
  return FractionalOffset.fromOffsetAndSize(
    offset - rect.topLeft,
    rect.size,
  );
}

六、Row Widget

Row 是一个可以同时显示多个子 Widget 的 Widget ,这些子 Widget 以水平方式进行排列。Row Widget 不是一个可以滚动的 Widget ,如果水平显示的子 Widget 的总范围超出了可用空间会抛出异常。如果有需要进行水平或垂直方向的滚动操作,考虑使用 ListView ,后面会讲到。Row 的构造方法如下:

Row({
  Key key,
  //MainAxisAlignment类型可选命名参数,如何沿着主轴放置子Widget
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
  //MainAxisSize类型可选命名参数,主轴上应占用多少空间,该值传入最大化还是最小化可用空间
  MainAxisSize mainAxisSize = MainAxisSize.max,
  //CrossAxisAlignment类型可选命名参数,如何沿着次轴放置子Widget
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
  //TextDirection类型可选命名参数,设置子Widget横向的排列方向,默认为环境方向
  TextDirection textDirection,
  //VerticalDirection类型可选命名参数,设置子Widget纵向的排列顺序以及如何解释垂直方向的开始和结束
  VerticalDirection verticalDirection = VerticalDirection.down,
  //TextBaseline类型可选命名参数,如果根据基线对齐项目,使用哪个基线
  TextBaseline textBaseline,
  //List<Widget>类型可选命名参数,要显示的子Widget列表
  List<Widget> children = const <Widget>[],
})

MainAxisAlignment 用于设置子 Widget 在主轴(这里是水平方向)上的排列方式,是一个枚举类型,有如下值:

enum MainAxisAlignment {
  //子Widget放置在尽可能靠近主轴起点的位置。如果在水平方向使用,则必须使
  //用TextDirection来确定起点是左侧还是右侧。如果在垂直方向上使用此值,
  //则VerticalDirection必须可用以确定起点是顶部还是底部
  start,

    //子Widget放置在尽可能靠近主轴末端的位置。如果在水平方向上使用此值,则必须使
  //用TextDirection来确定末端是左侧还是右侧。如果在垂直方向上使用此值,则必须
  //使用VerticalDirection来确定末端是顶部还是底部
  end,

  //子Widget放置在尽可能靠近主轴的中心
  center,

  //子Widget均匀的放置在可用空间内
  spaceBetween,

  //将自由空间平均放置在两个子Widget之间,以及第一个和最后一个Widget前后的一半空间
  spaceAround,

  //在子Widget之间以及第一个Widget和最后一个Widget之前和之后均匀地放置自由空间
  spaceEvenly,
}

CrossAxisAlignment 用于设置子 Widget 在次轴(这里是垂直方向)上的排列方式,是一个枚举类型,有如下值:

enum CrossAxisAlignment {
  //子Widget放置在尽可能靠近次轴起点的位置。如果在水平方向上使用此值,则必须使
  //用TextDirection来确定起点是左侧还是右侧。如果在垂直方向上使用此值,
  //则VerticalDirection必须可用以确定起点是顶部还是底部
  start,

  //子Widget放置在尽可能靠近次轴末端的位置。如果在水平方向上使用此值,则必须使
  //用TextDirection来确定末端是左侧还是右侧。如果在垂直方向上使用此值,则必须
  //使用VerticalDirection来确定末端是顶部还是底部
  end,

  //子Widget放置在尽可能靠近次轴的中心
  center,

  //子Widget填满次轴
  stretch,

  //在次轴上放置子Widget,使其与基线对齐,使用此值需要设置textBaseline
  baseline,
}

VerticalDirection 用于设置垂直的排列方向,是一个枚举类型值,有如下值:

enum VerticalDirection {
  //盒子应从底部开始,并垂直向上堆叠。“开始”在底部,“结束”在顶部。
  up,
  
  //盒子应从顶部开始,并垂直向下堆叠。“开始”在顶部,“结束”在底部。
  down,
}

Row 的使用方式如下:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(
        height: 100,
        color: Colors.yellow,
        child: Row(                         //Row
          textBaseline: TextBaseline.alphabetic,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: <Widget>[
//            Image.network("http://www.mwpush.com/uploads/avatar.png"),
            Container(child: Text("Row1"), color: Colors.red,),
            Text("Row2"),
            Text("Row3"),
          ],
        ),
      ),
    );
  }
}

效果如下:

20203231204.jpg

七、Column Widget

Column 是一个可以同时显示多个子 Widget 的 Widget ,这些子 Widget 以垂直方式进行排列。Column Widget 不是一个可以滚动的 Widget ,如果垂直显示的子 Widget 的总范围超出了可用空间会抛出异常。如果有需要进行水平或垂直方向的滚动操作,考虑使用 ListViewColumn 的构造方法如下:

Column({
  Key key,
  //MainAxisAlignment类型可选命名参数,如何沿着主轴放置子Widget
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
  //MainAxisSize类型可选命名参数,主轴上应占用多少空间,该值传入最大化还是最小化可用空间
  MainAxisSize mainAxisSize = MainAxisSize.max,
  //CrossAxisAlignment类型可选命名参数,如何沿着次轴放置子Widget
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
  //TextDirection类型可选命名参数,设置子Widget横向的排列方向,默认为环境方向
  TextDirection textDirection,
  //VerticalDirection类型可选命名参数,设置子Widget纵向的排列顺序以及如何解释垂直方向的开始和结束
  VerticalDirection verticalDirection = VerticalDirection.down,
  //TextBaseline类型可选命名参数,如果根据基线对齐项目,使用哪个基线
  TextBaseline textBaseline,
  //List<Widget>类型可选命名参数,要显示的子Widget列表
  List<Widget> children = const <Widget>[],
})

构造方法与 Row 相同,只是排列的基准不同。使用如下:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Container(
        width: 500,
        height: 200,
        color: Colors.yellow,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
//            Image.network("http://www.mwpush.com/uploads/avatar.png"),
            Container(child: Text("Row1"), color: Colors.red,),
            Text("Row2"),
            Text("Row3"),
          ],
        ),
      ),
    );
  }
}

效果如下:

20203231212.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 一、Image Widget Image Widget 是 Flutter 中用来显示图片的小部件。支持以下图像格...
    陌问MW阅读 4,055评论 0 5
  • 官方简介中,说 Container 组件是一个方便绘制、定位和调整子组件大小的组件。首先 Container 会在...
    窦豆逗阅读 1,062评论 0 0
  • Flutter布局入门 一、Widget简介 描述 Fullter的核心思想是用widget 来构建你的 UI 界...
    CYL_f78c阅读 1,068评论 0 1
  • 知我冷暖, 懂我悲欢; 内心笃定, 心怀美好; 虽然我不是最好的, 却是独一无二唯一一个; 确认过眼神, 从此心无...
    慢一点不要紧阅读 461评论 0 1
  • 在公海里赌博是合法,也不知道有没有进公海,我们练习上了:21点。 规矩不多说,在赌牌中能深刻地理解“概率”一词的意...
    妮子的世界阅读 239评论 0 0