Flutter 学习笔记(五) 页面布局 弹性盒布局 / 定位布局

652 阅读2分钟

Expanded 类似 Flex 布局

Expanded 可以用在 Row 和 Column 布局中

属性:

属性说明
flex元素站整个父 Row /Column 的比例
child子元素

与网格布局结合, 在每个item里面使用了Expanded,当然网格布局也可以childAspectRatio设置宽高的比例来解决内容布局问题,但是呈现的效果与目前的效果不同;可以尝试一下,使用childAspectRatio就不需要使用Expanded了;

这个是使用Expanded布局的效果 image.png

import 'res/listData.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('hello world'),
          elevation: 30, // 标题文字阴影
        ),
        body: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  List list = [];
  //- 父类创建list属性
  MyHomePage({Key? key}) : super(key: key) {
    for (var i = 0; i < 10; i++) {
      list.add('this is $i data');
    }
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> _getListData() {
      var list = listData.map((value) {
        return Container(
          child: Column(
            children: <Widget>[
              Expanded(
                flex: 3, //- 占3份
                child: Image.network(value['imageUrl']),
              ),
              Expanded(
                child: Padding(
                  padding: EdgeInsets.only(top: 12),
                  child: Text(
                    value['title'],
                    textAlign: TextAlign.center,
                    style: TextStyle(fontSize: 16),
                  ),
                ),
              ),
            ],
          ),
          decoration: BoxDecoration(
              border: Border.all(
                  color: Color.fromRGBO(233, 233, 233, 0.9), width: 1)),
          // height: 400, //设置高度没有反应
        );
      });

      return list.toList();
    }

    return GridView.count(
      crossAxisSpacing: 10.0, //水平子 Widget 之间间距
      mainAxisSpacing: 10.0, //垂直子 Widget 之间间距
      padding: EdgeInsets.all(10),
      crossAxisCount: 2, //一行的 Widget 数量
      // childAspectRatio: 0.5, //设置宽高的比例
      children: _getListData(),
    );
  }
}

完成简单布局案例

image.png

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Hello Demo')),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Row(children: <Widget>[
        Expanded(
          child: Container(
              height: 180.0, color: Colors.green, child: Text("hello world")),
        ),
      ]),
      SizedBox(height: 10),
      Row(children: <Widget>[
        Expanded(
          flex: 2,
          child: Container(
              child: Container(
            height: 400,
            child: Image.network(
                "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2635669599.jpg"),
          )),
        ),
        SizedBox(width: 10),
        Expanded(
            flex: 1,
            child: Container(
              child: Column(children: <Widget>[
                Container(
                  height: 195,
                  child: Image.network(
                      "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2641806535.jpg"),
                ),
                SizedBox(height: 10),
                Container(
                  height: 195,
                  child: Image.network(
                      "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2636337478.jpg"),
                ),
              ]),
            )),
      ]),
    ]);
  }
}

Stack 层叠组件

Stack 表示堆的意思,我们可以用 Stack 或者 Stack 结合 Align 或者 Stack 结合 Positiond 来实 现页面的定位布局

属性:

属性说明
alignment配置所有子元素的显示位置
children子元素

一个元素需要定位案例 image.png



class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
    alignment: Alignment.bottomRight,  //- 可以通过单词方式进行定位
    // alignment: Alignment(1, -1), //- 也可以通过调用 Alignment 方法进行定位,(0,0)表示居中
    children: <Widget>[
      Container(
        height: 280,
        width: 250,
        color: Colors.green,
      ),
      Text("hello wolrd", style: TextStyle(color: Colors.amber, fontSize: 30.0))
    ]);
  }
}

Flutter Stack Align

属性:

属性说明
alignment配置所有子元素的显示位置
children子元素

多个元素定位

image.png

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 280,
      width: 250,
      color: Colors.green,
      child: Stack(children: <Widget>[
        Align(
          alignment: Alignment.topLeft,
          child: Icon(Icons.home, size: 40, color: Colors.red),
        ),
        Align(
          alignment: Alignment.bottomCenter,
          child: Icon(Icons.search, size: 40, color: Colors.blue),
        ),
        Align(
          alignment: Alignment.bottomLeft,
          child: Icon(Icons.send, size: 40, color: Colors.orange),
        ),
      ]),
    );
  }
}

Flutter Stack Positioned

属性:

属性说明
top子元素距离顶部的距离
bottom子元素距离底部的距离
left子元素距离左侧距离
right子元素距离右侧距离
child子组件

image.png

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 280,
      width: 250,
      color: Colors.green,
      child: Stack(children: <Widget>[
        Positioned(
          left: 10,
          child: Icon(Icons.home, size: 40, color: Colors.red),
        ),
        Positioned(
          right: 10,
          bottom: 0,
          child: Icon(Icons.search, size: 40, color: Colors.blue),
        ),
        Positioned(
          right: 0,
          child: Icon(Icons.send, size: 40, color: Colors.orange),
        ),
      ]),
    );
  }
}