flutter学习笔记-容器类控件

单子 Widget 布局:

Container、Padding 与 CenterContainer

Container

是一种允许在其内部添加其他控件的控件,也是 UI 框架中的一个常见概念。


Container(
  child: Text('Container(容器)在UI框架中是一个很常见的概念,Flutter也不例外。'),
  padding: EdgeInsets.all(18.0), // 内边距
  margin: EdgeInsets.all(44.0), // 外边距
  width: 180.0,
  height:240,
  alignment: Alignment.center, // 子Widget居中对齐
  decoration: BoxDecoration( //Container样式
    color: Colors.red, // 背景色
    borderRadius: BorderRadius.circular(10.0), // 圆角边框
  ),
)

Padding

适合要设置内间距的单一控件


Padding(
  padding: EdgeInsets.all(44.0),
  child: Text('Container(容器)在UI框架中是一个很常见的概念,Flutter也不例外。'),
);

EdgeInsets提供的便捷方法:

1.fromLTRB(double left, double top, double right, double bottom):分别指定四个方向的填充。
2.all(double value) : 所有方向均使用相同数值的填充。
3.only({left, top, right ,bottom }):可以设置具体某个方向的填充(可以同时指定多个方向)。
4.symmetric({ vertical, horizontal }):用于设置对称方向的填充,vertical指top和bottom,horizontal指left和right。

Center

适合要居中排列的控件


Scaffold(
  body: Center(child: Text("Hello"))
   // This trailing comma makes auto-formatting nicer for build methods.
);


多子 Widget 布局:

Row、Column 与 Expanded

Row、

水平排列,类似于android的线性布局

Column

垂直排列,竖向排列的线性布局

Expanded

布局方向(行 / 列)中剩余空间的 Expanded

横向排列,expanded 填充剩余空间。
Row(
  children: <Widget>[
    Expanded(flex: 1, child: Container(color: Colors.yellow, height: 60)), //设置了flex=1,因此宽度由Expanded来分配
    Container(color: Colors.red, width: 100, height: 180,),
    Container(color: Colors.black, width: 60, height: 80,),
    Expanded(flex: 1, child: Container(color: Colors.green,height: 60),)/设置了flex=1,因此宽度由Expanded来分配
  ],
); 

mainAxisAlignment

滚动的方向叫做主轴。主轴方向 start 表示靠左对齐、center 表示横向居中对齐、end 表示靠右对齐、
spaceEvenly 表示按固定间距对齐;

crossAxisAlignment

纵轴,和主轴垂直的方向叫纵轴
而纵轴方向 start 则表示靠上对齐、center 表示纵向居中对齐、end 表示靠下对齐


Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly, //由于容器与子Widget一样宽,因此这行设置排列间距的代码并未起作用
  mainAxisSize: MainAxisSize.min, //让容器宽度与所有子Widget的宽度一致
  children: <Widget>[
    Container(color: Colors.yellow, width: 60, height: 80,),
    Container(color: Colors.red, width: 100, height: 180,),
    Container(color: Colors.black, width: 60, height: 80,),
    Container(color: Colors.green, width: 60, height: 80,),
  ],
)

层叠 Widget 布局:

Stack 与 Positioned

Stack 提供了层叠布局的容器,而 Positioned 则提供了设置子 Widget 位置的能力。Positioned 控件只能在 Stack 中使用,在其他容器中使用会报错


Stack(
  children: <Widget>[
    Container(color: Colors.yellow, width: 300, height: 300),//黄色容器
    Positioned(
      left: 18.0,
      top: 18.0,
      child: Container(color: Colors.green, width: 50, height: 50),//叠加在黄色容器之上的绿色控件
    ),
    Positioned(
      left: 18.0,
      top:70.0,
      child: Text("Stack提供了层叠布局的容器"),//叠加在黄色容器之上的文本
    )
  ],
)

限制类容器

尺寸限制类容器用于限制容器大小。
ConstrainedBox、SizedBox、UnconstrainedBox(不限制容器,不常用)

ConstrainedBox

用于对子组件添加额外的约束。例如,如果你想让子组件的最小高度是80像素,你可以使用const BoxConstraints(minHeight: 80.0)作为子组件的约束

ConstrainedBox(
  constraints: BoxConstraints(
    minWidth: double.infinity, //宽度尽可能大
    minHeight: 50.0 //最小高度为50像素
  ),
  child: Container(
      height: 5.0, 
      child: redBox 
  ),
)

SizedBox

用于给子元素设置固定的宽高

SizedBox(
  width: 80.0,
  height: 80.0,
  child: redBox
)

组合和组装控件

实现该效果


class UpdatedItem extends StatelessWidget {
  final UpdatedItemModel model;//数据模型
  //构造函数语法糖,用来给model赋值
  UpdatedItem({Key key,this.model, this.onPressed}) : super(key: key);
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return Column(//用Column将上下两部分合体
        children: <Widget>[
          buildTopRow(context),//上半部分
          buildBottomRow(context)//下半部分
        ]);
  }
  Widget buildBottomRow(BuildContext context) {...}
  Widget buildTopRow(BuildContext context) {...}
}




Widget buildTopRow(BuildContext context) {
  return Row(//Row控件,用来水平摆放子Widget
    children: <Widget>[
      Padding(//Paddng控件,用来设置Image控件边距
        padding: EdgeInsets.all(10),//上下左右边距均为10
        child: ClipRRect(//圆角矩形裁剪控件
          borderRadius: BorderRadius.circular(8.0),//圆角半径为8
          child: Image.asset(model.appIcon, width: 80,height:80)图片控件//
        )
      ),
      Expanded(//Expanded控件,用来拉伸中间区域
        child: Column(//Column控件,用来垂直摆放子Widget
          mainAxisAlignment: MainAxisAlignment.center,//垂直方向居中对齐
          crossAxisAlignment: CrossAxisAlignment.start,//水平方向居左对齐
          children: <Widget>[
            Text(model.appName,maxLines: 1),//App名字
            Text(model.appDate,maxLines: 1),//App更新日期
          ],
        ),
      ),
      Padding(//Paddng控件,用来设置Widget间边距
        padding: EdgeInsets.fromLTRB(0,0,10,0),//右边距为10,其余均为0
        child: FlatButton(//按钮控件
          child: Text("OPEN"),
          onPressed: onPressed,//点击回调
        )
      )
  ]);
}


Widget buildBottomRow(BuildContext context) {
  return Padding(//Padding控件用来设置整体边距
    padding: EdgeInsets.fromLTRB(15,0,15,0),//左边距和右边距为15
    child: Column(//Column控件用来垂直摆放子Widget
      crossAxisAlignment: CrossAxisAlignment.start,//水平方向距左对齐
      children: <Widget>[
        Text(model.appDescription),//更新文案
        Padding(//Padding控件用来设置边距
          padding: EdgeInsets.fromLTRB(0,10,0,0),//上边距为10
          child: Text("${model.appVersion}${model.appSize} MB")
        )
      ]
  ));
}

自绘

CustomPaint 是用以承接自绘控件的容器,并不负责真正的绘制。既然是绘制,那就需要用到画布与画笔。
画布是 Canvas,画笔则是 Paint


class WheelPainter extends CustomPainter {
 // 设置画笔颜色 
  Paint getColoredPaint(Color color) {//根据颜色返回不同的画笔
    Paint paint = Paint();//生成画笔
    paint.color = color;//设置画笔颜色
    return paint;
  }

  @override
  void paint(Canvas canvas, Size size) {//绘制逻辑
    double wheelSize = min(size.width,size.height)/2;//饼图的尺寸
    double nbElem = 6;//分成6份
    double radius = (2 * pi) / nbElem;//1/6圆
    //包裹饼图这个圆形的矩形框
    Rect boundingRect = Rect.fromCircle(center: Offset(wheelSize, wheelSize), radius: wheelSize);
    // 每次画1/6个圆弧
    canvas.drawArc(boundingRect, 0, radius, true, getColoredPaint(Colors.orange));
    canvas.drawArc(boundingRect, radius, radius, true, getColoredPaint(Colors.black38));
    canvas.drawArc(boundingRect, radius * 2, radius, true, getColoredPaint(Colors.green));
    canvas.drawArc(boundingRect, radius * 3, radius, true, getColoredPaint(Colors.red));
    canvas.drawArc(boundingRect, radius * 4, radius, true, getColoredPaint(Colors.blue));
    canvas.drawArc(boundingRect, radius * 5, radius, true, getColoredPaint(Colors.pink));
  }
  // 判断是否需要重绘,这里我们简单的做下比较即可
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => oldDelegate != this;
}
//将饼图包装成一个新的控件
class Cake extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomPaint(
        size: Size(200, 200),
        painter: WheelPainter(),
      );
  }
}
发布了58 篇原创文章 · 获赞 1 · 访问量 6856

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/103545810