美文网首页
常用Widget和弹性盒子布局

常用Widget和弹性盒子布局

作者: 浅墨入画 | 来源:发表于2021-11-20 18:56 被阅读0次

抽取Widget

上篇文章我们在写ListView的时候,所有的代码都写在main.dart文件内容,这样的话就比较臃肿,下面进行拆分优化

  • 新建listview_demo.dart文件,把_itemForRow抽出来
import 'package:flutter/material.dart';
import 'model/Car.dart';

class ListViewDemo extends StatelessWidget {
  Widget _itemForRow(BuildContext context, int index) {
    return Container(
        color: Colors.white,
        margin: const EdgeInsets.all(10),
        child: Column(
          children: <Widget>[
            Image.network(datas[index].imageUrl!),
            const SizedBox(
              height: 10,
            ),
            Text(
              datas[index].name!,
              style: const TextStyle(
                fontWeight: FontWeight.w800,
                fontSize: 18.0,
                fontStyle: FontStyle.italic,
              ),
            ),
          ],
        ));
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Colors.grey[100],
      appBar: AppBar(
        title: const Text('FlutterDemo'),
      ),
      body: ListView.builder(
        itemBuilder: _itemForRow,
        itemCount: datas.length,
      ),
    );
  }
}
  • 抽取main.dart文件中的数据源,放入Car.dart文件
class Car {
  const Car({this.name, this.imageUrl});
  final String? name;
  final String? imageUrl;
}

final List<Car> datas = [
  const Car(
    name: '保时捷918 Spyder',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '兰博基尼Aventador',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '法拉利Enzo',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: 'Zenvo ST1',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '迈凯伦F1',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '萨林S7',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '科尼赛克CCR',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '布加迪Chiron',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '轩尼诗Venom GT',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  const Car(
    name: '西贝尔Tuatara',
    imageUrl:
    'https://img.haomeiwen.com/i2990730/3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  )
];
  • main.dart文件内容如下
import 'package:flutter/material.dart';
import 'package:hello_flutter/listview_demo.dart';

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ListViewDemo(),
    );
  }
}
运行效果

常用Widget

富文本RichText小部件练习
  • 新建base_widget.dart文件
// base_widget.dart文件内容
import 'package:flutter/material.dart';

class RichTextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
  • main.dart文件引入RichTextDemo
import 'package:flutter/material.dart';
import 'package:hello_flutter/base_widget.dart';

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.grey[100],
        appBar: AppBar(
          title: const Text('BaseDemo'),
        ),
        body: RichTextDemo()
      )
    );
  }
}
  • base_widget.dart开始编写练习
  1. Text()定义style的两种方式
// 方式一
class RichTextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(
      'flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习',
      textAlign: TextAlign.center,
      style: TextStyle(color: Colors.orange),
    );
  }
}

// 方式二
class RichTextDemo extends StatelessWidget {

  final TextStyle _textStyle = TextStyle(color: Colors.orange);

  @override
  Widget build(BuildContext context) {
    return Text(
      'flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习',
      textAlign: TextAlign.center,
      style: _textStyle,
    );
  }
}
  1. 字符串拼接展示
class RichTextDemo extends StatelessWidget {

  final TextStyle _textStyle = TextStyle(color: Colors.orange);
  final String _str1 = 'hello';

  @override
  Widget build(BuildContext context) {
    return Text(
      // 使用$拼接字符串_str1
      '$_str1 flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习flutter学习',
      textAlign: TextAlign.center,
      style: _textStyle,
      // 最大行数
      maxLines: 3, 
      // 超过3行显示...
      overflow: TextOverflow.ellipsis,
    );
  }
}
  1. RichText练习
class RichTextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // RichText表示富文本
    return RichText(
      // 使用TextSpan可以有多个子部件
      text: const TextSpan(
          text: '《Flutter高级学习》',
          style: TextStyle(
            fontSize: 30,
            color: Colors.black,
          ),
          children: [
            TextSpan(
                text: '--',
                style: TextStyle(
                  fontSize: 20,
                  color: Colors.red,
                )),
            TextSpan(
                text: 'HK',
                style: TextStyle(fontSize: 16, color: Colors.blue)),
          ]),
    );
  }
}
运行效果
Container小部件练习
class RichTextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 父部件Container会随着子部件变化
    return Container(
      color: Colors.yellow,
      child: Row(
        children: <Widget>[
          // 注意⚠️ Container 不能被 const修饰
          Container(
            color: Colors.red,
            // 添加子部件Icon,有了子部件 父视图Container才能够显示出来
            child: Icon(
              Icons.add,
              size: 45,
            ),
            padding: EdgeInsets.all(20), //内边距
            margin: EdgeInsets.all(20), //外边距
            height: 200,
          ),
        ],
      ),
    );
  }
}
运行效果

Flutter布局之Row&Column&Stack

  • Row:在水平方向上排列子widget的列表,主轴方向向右
  • Column:在垂直方向上排列子widget的列表,主轴方向向下
  • Stack:多层 -> 层叠样式,主轴方向向外

常用的属性有:
MainAxisAlignment:主轴方向上的对齐方式,会对child的位置起作用,默认是start。

其中MainAxisAlignment枚举值:
center:将children放置在主轴的中心
end:将children放置在主轴的末尾
spaceAround:将主轴方向上的空白区域均分,使得children之间的空白区域相等,但是首尾child的空白区域为1/2
spaceBetween:将主轴方向上的空白区域均分,使得children之间的空白区域相等,首尾child都靠近首尾,没有间隙
spaceEvenly:将主轴方向上的空白区域均分,使得children之间的空白区域相等,包括首尾child
start:将children放置在主轴的起点

交叉轴CrossAxisAlignment枚举值:
start:将子控件放在交叉轴的起始位置
end:将子控件放在交叉轴的结束位置
center:将子控件放在交叉轴的中间位置
stretch:使子控件填满交叉轴
baseline:将子控件放在交叉轴的上,并且与基线相匹配(不常用)

Expanded填充布局

  1. 在主轴方向不会剩下间隙。将被Expanded包装的部件进行拉伸和压缩
  2. 主轴横向,宽度设置没有意义
  3. 主轴纵向,高度设置没有意义
  4. TextExpanded包装后,文字可以自动换行,这也被称作灵活布局
  • 新建layout_demo.dart文件
import 'package:flutter/material.dart';

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 这里的Container就是mian.dart中的body小部件
    return Container(
      color: Colors.yellow,
      // 设置子部件Row放置在中心点,值的区间 -1 ~ 1,x值不能影响Row y值不能影响Column
      alignment: Alignment(0.0, 0.0),
      child: Row(
        //spaceBetween:  剩下的空间平均分布到小部件之间!!
        //spaceAround: 剩下的空间平均分布到小部件周围!!
        //spaceEvenly:剩下的空间和小部件一起平均分!!
        mainAxisAlignment: MainAxisAlignment.spaceEvenly, //主轴

        // crossAxisAlignment与textBaseline配合使用,主要用来设置文本对齐
        crossAxisAlignment: CrossAxisAlignment.baseline, //交叉轴
        //CrossAxisAlignment.baseline需要结合textBaseline一起使用
        //alphabetic是设置英文字符,ideographic设置中文字符
        textBaseline: TextBaseline.alphabetic,
        children: [
          //Expanded:在主轴方向不会剩下间隙。将被Expanded拉伸。
          //Expanded用于自适应拉伸
          Expanded(
              child: Container(
                  child: Text(
                    '你好hello',
                    style: TextStyle(fontSize: 15),
                  ),
                  color: Colors.red)),
          Expanded(
              child: Container(
                  child: Text(
                    '哎aiyo',
                    style: TextStyle(fontSize: 30),
                  ),
                  color: Colors.blue)),
          Expanded(
              child: Container(
                  child: Text(
                    '哎aiyo',
                    style: TextStyle(fontSize: 60),
                  ),
                  color: Colors.white)),
        ],
      ),
    );
  }
}
Row横向布局 Column纵向布局 Stack层叠布局

Row添加textDirection: TextDirection.rtl,属性,可以让子部件从右向左排列。在Row布局中能够改变主轴方向

return Container(
      color: Colors.yellow,
      // 设置子部件Row放置在中心点,值的区间 -1 ~ 1,x值不能影响Row y值不能影响Column
      alignment: Alignment(0.0, 0.0),
      child: Row(
        // 添加排列方向
        textDirection: TextDirection.rtl,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly, //主轴
        crossAxisAlignment: CrossAxisAlignment.baseline, //交叉轴
        textBaseline: TextBaseline.alphabetic,
        children: [
          //Expanded:在主轴方向不会剩下间隙。将被Expanded拉伸。
          //Expanded用于自适应拉伸
          Expanded(
              child: Container(
                  child: Text(
                    '你好hello',
                    style: TextStyle(fontSize: 15),
                  ),
                  color: Colors.red)),
          Expanded(
              child: Container(
                  child: Text(
                    '哎aiyo',
                    style: TextStyle(fontSize: 30),
                  ),
                  color: Colors.blue)),
          Expanded(
              child: Container(
                  child: Text(
                    '哎aiyo',
                    style: TextStyle(fontSize: 60),
                  ),
                  color: Colors.white)),
        ],
      ),
    );
运行效果

相关文章

  • 常用Widget和弹性盒子布局

    抽取Widget 上篇文章[https://www.jianshu.com/p/bcae648e6f51]我们在写...

  • Flutter布局Widget--弹性布局、线性布局、流式布局和

    前言 本文我们要介绍 Flutter 中布局 Widget,包括弹性布局、线性布局流式布局和层叠布局。 一、弹性布...

  • Flutter -- 5.布局相关

    Flutter中,布局方式为弹性盒子布局 可以将一个一个Widget看做一个一个矩形盒子,盒子套盒子模式 1.Co...

  • flutter 动手篇2 - 弹性布局 Flex

    弹性布局 Flex 弹性布局 弹性布局允许子widget按照一定比例来分配父容器空间,弹性布局的概念在其UI系统中...

  • 弹性盒子的布局

    1 弹性盒子(弹性布局)1.1 弹性布局介绍 Flexbox是flexible box的简称(意思是"灵活的盒子容...

  • flex布局

    1、什么是flex布局? flex布局又叫弹性布局,弹性盒子,与怪异和模型布局不同,其布局能更精准。 2、如何设置...

  • CSS3弹性布局和多列布局

    弹性盒子基础 弹性盒子(Flexible Box)是css3中盒子模型的弹性布局,在传统的布局方式上增加了很多灵活...

  • 弹性盒子--Flexbox布局!!

    弹性盒子布局模型 1. Flex布局是什么? Flex是发了flexbox 的缩写,意为“弹性布局”,用来为盒子状...

  • Flutter widget3

    widget 综合布局 弹性布局:Flex ,Expanded线性布局:Row,Column--(都继承Flex)...

  • 几个好玩的flex布局案例

    弹性盒子布局flex,为自适应布局而生 弹性盒子布局的选项很多(选项越多->越专业->越难记), 但对于普通的开发...

网友评论

      本文标题:常用Widget和弹性盒子布局

      本文链接:https://www.haomeiwen.com/subject/plhytrtx.html