Flutter设置背景图片

19次阅读

共计 5210 个字符,预计需要花费 14 分钟才能阅读完成。

效果展示

前言

在我们平时的开发中会经常使用到背景图片,下面我这介绍的是 Container 通过 BoxDecoration 来设置的

布局

1、创建路由子页面

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("优选访客订阅功能"),
      ),
      body: buildBody());
  }

Scaffold

路由页面的骨架,我们在里面可以拼装出一个完整的路由页面

appBar

创建导航栏

body

构建页面主体结构

2、页面布局

Widget buildBody() {
    return new Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[buildHeader(),
        // Row(children: <Widget>[
        //   Text(
        //     '批量管理功能',
        //     style:TextStyle(
        //       fontSize: 16.0,
        //       color: Color.fromRGBO(234,200,134,1)
        //     )
        //   )
        // ],)
      ],
    );
  }

为了后续方便维护,在页面布局时最好都拆分成不同的小模块来分开写,不然后期太难维护

Column

即指沿水平或垂直方向排布子组件。Flutter 中通过 RowColumn来实现线性布局;

首先布局思路就是使用 Column 可以在垂直方向排列其子组件。

mainAxisAlignment

然后在把里面的子元素都按主轴方向对齐

3、背景设置

Widget buildHeader() {
    return new Container(
      height: 160.0,
      width: MediaQuery.of(context).size.width,
      decoration: BoxDecoration(
        image: DecorationImage(image: AssetImage("images/header.png"),
          fit: BoxFit.cover
        )
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        // alignment: WrapAlignment.center,
        // crossAxisAlignment: WrapCrossAlignment.center,
        // runSpacing: 9.0,
        children: <Widget>[
          Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                '批量管理功能',
                style:TextStyle(
                  fontSize: 16.0,
                  color: Color.fromRGBO(234,200,134,1)
                )
              )
            ],
          ),
          Wrap(
            runSpacing: 9.0,
            alignment: WrapAlignment.center,
            children: <Widget>[
              Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('${pageData['title']}',
                    style:TextStyle(
                      fontSize: 38.0,
                      color: Color.fromRGBO(234,200,134,1)
                    )
                  )
                ],
              ),
              // 自定义圆角
              ClipRRect(borderRadius: BorderRadius.circular(12.5),
                child: Container(
                  height: 25.0,
                  width: 190.0,
                  color: Color.fromRGBO(234,200,134,1),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text('${pageData['subTitle']}', 
                        textAlign: TextAlign.center,
                        style: TextStyle(color: Color.fromRGBO(113,80,24,1)),
                      )
                    ]
                  )
                )
              )
            ],
          )
        ],
      ),
    );
  }

首先是把头部 banner 部分放在一个方法里面使用 Container 容器组件来包裹

Container

容器组件

MediaQuery.of(context).size 获取屏幕的大小

设置容器大小:

height: 160.0, // 高度自定义
width: MediaQuery.of(context).size.width, // 宽度设置和屏幕等宽
decoration
decoration: BoxDecoration(
    image: DecorationImage(image: AssetImage("images/header.png"),
      fit: BoxFit.cover
    )
  ),

Container组件的一个属性,用来装饰背景的;

我们通常会直接使用 BoxDecoration 类,它是一个 Decoration 的子类,实现了常用的装饰元素的绘制。

BoxDecoration({
  Color color, // 颜色
  DecorationImage image,// 图片
  BoxBorder border, // 边框
  BorderRadiusGeometry borderRadius, // 圆角
  List<BoxShadow> boxShadow, // 阴影, 可以指定多个
  Gradient gradient, // 渐变
  BlendMode backgroundBlendMode, // 背景混合模式
  BoxShape shape = BoxShape.rectangle, // 形状
})

使用 DecorationImage 方法来装载图片

image: DecorationImage(image: AssetImage("images/header.png"), // 加载本地图片
  fit: BoxFit.cover // 图片伸缩方式
)
image 图片配置

pubspec.yaml 中的 flutter 部分添加如下内容:

assets:
    - images/header.png

Wrap 流式布局

Wrap({
  ...
  this.direction = Axis.horizontal,
  this.alignment = WrapAlignment.start,
  this.spacing = 0.0,
  this.runAlignment = WrapAlignment.start,
  this.runSpacing = 0.0,
  this.crossAxisAlignment = WrapCrossAlignment.start,
  this.textDirection,
  this.verticalDirection = VerticalDirection.down,
  List<Widget> children = const <Widget>[],})
  • spacing:主轴方向子 widget 的间距
  • runSpacing:纵轴方向的间距
  • runAlignment:纵轴方向的对齐方式

ClipRRect

将子组件剪裁为圆角矩形

 ClipRRect({ 
     ...
     BorderRadius borderRadius, 
     CustomClipper<RRect> clipper, 
     Clip clipBehavior = Clip.antiAlias, 
     Widget child
     ...
 })

完整 demo

import 'package:flutter/material.dart';

const pageData = {
    "discountStatus": 2, 
    "subscribeStatus": "0", 
    "title": "限时免费", 
    "subTitle": "活动时间 9 月 1 日 - 9 月 30 日", 
    "packageList": [
        {
            "id": 23, 
            "desc": "月度订阅", 
            "dealPrice": 10, 
            "originPrice": 50, 
            "recommand": 1
        }, 
        {
            "id": 33, 
            "desc": "半年订阅", 
            "dealPrice": 56, 
            "originPrice": 280, 
            "recommand": 0
        }, 
        {
            "id": 56, 
            "desc": "年度订阅", 
            "dealPrice": 108, 
            "originPrice": 540, 
            "recommand": 0
        }
    ]
};
class BatchSub extends StatefulWidget {
  @override
  createState() => new BatchSubState();
  
}

class BatchSubState extends State<BatchSub> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("优选访客订阅功能"),
      ),
      body: buildBody());
  }
  Widget buildBody() {
    return new Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[buildHeader(),
        // Row(children: <Widget>[
        //   Text(
        //     '批量管理功能',
        //     style:TextStyle(
        //       fontSize: 16.0,
        //       color: Color.fromRGBO(234,200,134,1)
        //     )
        //   )
        // ],)
      ],
    );
  }
  Widget buildHeader() {
    return new Container(
      height: 160.0,
      width: MediaQuery.of(context).size.width,
      decoration: BoxDecoration(
        image: DecorationImage(image: AssetImage("images/header.png"),
          fit: BoxFit.cover
        )
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        // alignment: WrapAlignment.center,
        // crossAxisAlignment: WrapCrossAlignment.center,
        // runSpacing: 9.0,
        children: <Widget>[
          Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                '批量管理功能',
                style:TextStyle(
                  fontSize: 16.0,
                  color: Color.fromRGBO(234,200,134,1)
                )
              )
            ],
          ),
          Wrap(
            runSpacing: 9.0,
            alignment: WrapAlignment.center,
            children: <Widget>[
              Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('${pageData['title']}',
                    style:TextStyle(
                      fontSize: 38.0,
                      color: Color.fromRGBO(234,200,134,1)
                    )
                  )
                ],
              ),
              // 自定义圆角
              ClipRRect(borderRadius: BorderRadius.circular(12.5),
                child: Container(
                  height: 25.0,
                  width: 190.0,
                  color: Color.fromRGBO(234,200,134,1),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text('${pageData['subTitle']}', 
                        textAlign: TextAlign.center,
                        style: TextStyle(color: Color.fromRGBO(113,80,24,1)),
                      )
                    ]
                  )
                )
              )
            ],
          )
        ],
      ),
    );
  }
}

正文完
 0