likes
comments
collection
share

Container容器组件的使用

作者站长头像
站长
· 阅读数 6

Container容器组件的使用

Container(容器控件)在Flutter是经常使用的控件,它就相当于我们HTML里的div标签,每个页面或者说每个视图都离不开它

Alignment属性

  • bottomCenter:下部居中对齐。
  • botomLeft: 下部左对齐。
  • bottomRight:下部右对齐。
  • center:纵横双向居中对齐。
  • centerLeft:纵向居中横向居左对齐。
  • centerRight:纵向居中横向居右对齐。
  • topLeft:顶部左侧对齐。
  • topCenter:顶部居中对齐。
  • topRight: 顶部居左对齐。

代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override 
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Text widget',
      home: Scaffold(
        body: Center(
          child: Container(
            child: new Text('Hello LXS',style:TextStyle(fontSize:40.0),),
            alignment: Alignment.center,
            width: 500.0,
            height: 400.0,
            color: Colors.lightBlue,
          ),
        ),
      ),
    );
  }
}

padding属性

padding的属性就是一个内边距,它和你使用的前端技术CSS里的padding表现形式一样,指的是Container边缘和child内容的距离。

padding简易书写方式

padding: const EdgeInsets.all(20),

EdgeInsets.all(20)很多情况并不满足我们的需求,所以:

padding: const EdgeInsets.fromLTRB(10,30,20,20),

我们用EdgeInsets.fromLTRB(value1,value2,value3,value4) 可以满足我们的需求,LTRB分别代表左、上、右、下

margin属性

margin是外边距,只的是container和外部元素的距离。 现在要把container的外边距设置为10个单位,代码如下:

margin: const EdgeInsets.all(10.0),

margin 同样拥有自定义的能力:

margin: const EdgeInsets.fromLTRB(10.0,30.0,10.0,10.0)

decoration属性

decoration是 container 的修饰器,主要的功能是设置背景和边框。 比如你需要给背景加入一个渐变,这时候需要使用BoxDecoration这个类,代码如下(需要注意的是如果你设置了decoration,就不要再设置color属性了,因为这样会冲突)。

child: Container(
            child: new Text('Hello LXS',style:TextStyle(fontSize:40.0),),
            alignment: Alignment.topLeft,
            width: 500.0,
            height: 400.0,
            // color: Colors.lightBlue,
            padding: const EdgeInsets.fromLTRB(10,30,20,20),
            margin: const EdgeInsets.fromLTRB(10.0,30.0,10.0,10.0),
            decoration: new BoxDecoration(
              gradient: const LinearGradient(
                colors: [Colors.lightBlue,Colors.greenAccent,Colors.purple]
              )
            ),
          ),

注意:一定要去掉color属性

border 边框

设置边框可以在decoration里设置border属性,比如你现在要设置一个红色边框,宽度为5。代码如下:

child: Container(
            child: new Text('Hello LXS',style:TextStyle(fontSize:40.0),),
            alignment: Alignment.topLeft,
            width: 500.0,
            height: 400.0,
            padding: const EdgeInsets.fromLTRB(10,30,20,20),
            margin: const EdgeInsets.fromLTRB(10.0,30.0,10.0,10.0),
            decoration: new BoxDecoration(
              gradient: const LinearGradient(
                colors: [Colors.lightBlue,Colors.greenAccent,Colors.purple]
              ),
              border: Border.all(width: 5.0,color: Colors.red)
            ),
          ),

主要代码是:

border:Border.all(width:5.0,color:Colors.red)

Image图片组件的使用

在程序中图片必不可少,接下来学习一下图片的使用:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp (
      title: 'Text Widget',
      home: Scaffold(
        body:Center(
          child:Container(
            child: new Image.network(
              'https://img2.woyaogexing.com/2019/06/09/dd1cce5fd57e48e8911a8fc9e872979d!400x400.jpeg',
               scale:1.0
            ),
            width:300.0,
            height:200.0,
            color:Colors.lightBlue
          ),
        ),
      ),
    );
  }
}

加入图片的几种方式

  • Image.asset:加载资源图片,就是加载项目资源目录中的图片,加入图片后会增大打包的包体体积,用的是相对路径。
  • Image.network:网络资源图片,意思就是你需要加入一段http://xxxx.xxx的这样的网络路径地址。
  • Image.file:加载本地图片,就是加载本地文件中的图片,这个是一个绝对路径,跟包体无关。
  • Image.memory: 加载Uint8List资源图片,这个我目前用的不是很多,所以没什么发言权。

fit属性的设置

fit属性可以控制图片的拉伸和挤压,这些都是根据图片的父级容器来的,我们先来看看这些属性(建议此部分组好看视频理解)。

  • BoxFit.fill:全图显示,图片会被拉伸,并充满父容器。
  • BoxFit.contain:全图显示,显示原比例,可能会有空隙。
  • BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。
  • BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。
  • BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。
  • BoxFit.scaleDown:效果和contain差不多,但是此属性不允许显示超过源图片大小,可小不可大。
child:Container(
            child: new Image.network(
              'https://img2.woyaogexing.com/2019/06/09/dd1cce5fd57e48e8911a8fc9e872979d!400x400.jpeg',
               fit: BoxFit.fill,
            ),
            width:300.0,
            height:200.0,
            color:Colors.lightBlue
          ),

图片的混合模式

图片混合模式(colorBlendMode)和color属性配合使用,能让图片改变颜色,里边的模式非常的多,产生的效果也是非常丰富的。在这里作几个简单的例子,让大家看一下效果,剩下的留给小伙伴自己探索

child:new Image.network(
  'https://img2.woyaogexing.com/2019/06/09/dd1cce5fd57e48e8911a8fc9e872979d!400x400.jpeg',
    color: Colors.greenAccent,
    colorBlendMode: BlendMode.darken,
    width: 100,
    height: 100,
),

color:是要混合的颜色,如果你只设置color是没有意义的。 colorBlendMode:是混合模式,相当于我们如何混合。

repeat图片重复

基本使用代码:

child: new Image.network(
              'https://img2.woyaogexing.com/2019/06/09/dd1cce5fd57e48e8911a8fc9e872979d!400x400.jpeg',
              repeat: ImageRepeat.repeatY,
              width: 100,
              height: 100,
            ),
  • ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布
  • ImageRepeat.repeatX: 横向重复,纵向不重复
  • ImageRepeat.repeatY:纵向重复,横向不重复
  • ImageRepeat.noRepeat:单图显示,不重复

还有非常多炫酷的效果大家可以自己尝试

ListView 列表组件简介

列表组件的知识其实是很多的,也是一个经常使用的组件,这节我们先学习最简单的列表组件如何制作。

话不多说线上代码,代码如下:

import 'package:flutter/material.dart';

void main () => runApp(MyApp());
///纵向列表
class MyApp extends StatelessWidget {
  @override 
  Widget build (BuildContext context) {
    return MaterialApp(
      title: 'LXS Flutter Demo',
      home: Scaffold(
        appBar: new AppBar(
          title: new Text('listView Widget'),
        ),
        // body: new Text('ListView Widget'),
        body: new ListView(
          children: <Widget>[
          //  new ListTile (
          //    leading:new Icon(Icons.access_time),
          //    title: new Text('access_time')
          //  ),
          //  new ListTile (
          //    leading:new Icon(Icons.accessibility),
          //    title: new Text('accessibility')
          //  ), 
          //  new ListTile (
          //    leading:new Icon(Icons.add_a_photo),
          //    title: new Text('add_a_photo')
          //  ),  
            new Image.network(
              'https://jspang.com/images/bilibili_count.jpg',
              fit: BoxFit.fitWidth,
              repeat: ImageRepeat.repeatX,
              // height:100.0,

            ),
            new Image.network(
              'https://jspang.com/images/bilibili_count.jpg',
              fit: BoxFit.fitWidth,
              repeat: ImageRepeat.repeatY,
              //  height:200.0,
              ),
            new Image.network(
              'https://jspang.com/images/bilibili_count.jpg',
              fit: BoxFit.fitWidth,
              repeat: ImageRepeat.repeatY,
              // height:300.0,
              ),
          ],
        ),
        // backgroundColor: Colors.blue,
      ),
    );
  }
}

制作横向列表

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override 
  Widget build(BuildContext context) {
    return MaterialApp (
      title: 'Text Widget',
      home: Scaffold(
        body: Center(
          child: Container(
            height: 200.0,
            child: MyList(),
          ),
        ),
      ),
    );
  }
}

class MyList extends StatelessWidget {
  @override 
  Widget build (BuildContext context) {
    return ListView (
      scrollDirection: Axis.horizontal,
      children: <Widget>[
        new Container(
          width: 180.0,
          color: Colors.lightBlue,
        ),
        new Container(
          width: 180.0,
          color: Colors.amber,
        ),
        new Container(
          width: 180.0,
          color: Colors.deepOrange,
        ),
        new Container(
          width: 180.0,
          color: Colors.deepPurple,
        ),
      ],
    );
  }
}

横向列表和竖向列表最大的不同在于: scrollDirection

  • Axis.vertical:默认值,竖向排列
  • Axis.horizontal:水平排列

其次MyList做了一个简单地代码分离,代码可读性更高

动态列表

动态列表顾名思义,数据不是写死的也是我们在实际项目中常用的,比如我们的数据从后台读取过来,然后存入一个变量数组里,然后以数组的内容循环出一个列表,先上代码在解释:

import 'package:flutter/material.dart';

void main() => runApp(MyApp(
  items:new List<String>.generate(1000, (i)=>"Item $i")
));

class MyApp extends StatelessWidget {

  final List<String> items;

  MyApp({Key key,@required this.items}): super(key : key);

  @override 
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ListView widget',
      home: Scaffold(
        body: new ListView.builder(
          itemCount: items.length,
          itemBuilder: (context,index){
            return new ListTile(
              title: new Text('${items[index]}'),
            );
          },
        ),
      ),
    );
  }
}

首先我们先介绍数据的来源(当然我这的数据也是假的):

void main() => runApp(MyApp(
  items:new List<String>.generate(1000, (i)=>"Item $i")
));

List类型的使用:

  • var myList = List(): 非固定长度的声明。
  • var myList = List(2): 固定长度的声明。
  • var myList= List():固定类型的声明方式。
  • var myList = [1,2,3]: 对List直接赋值。

我们使用的事List传递,然后直接用List方法中的generate产生List中的元素,最后产生一个带值的List数组

说明:再main函数的runApp中调用了MyApp类,再使用类的使用传递了一个items参数,并使用generate生成器对items进行赋值

generate方法传递两个参数,第一个参数是生成的个数,第二个是方法

参数传递完成,接下来我们看看怎么接收的:

接收参数

  ///final:只能被设一次值,在声明处赋值,值和普通变量的设值一样,可以是对象、字符串、数字等,用于修饰值的表达式不变的变量  
  ///const:只能被设一次值,在声明处赋值,且值必须为编译时常量;用于修饰常量。
  final List<String> items;
  
  MyApp({Key key,@required this.items}): super(key : key);

MyApp(...)是一个构造函数,除了Key,我们增加了一个必传参数,这里的@required意思就必传。:super如果父类没有无名无参数的默认构造函数,则子类必须手动调用一个父类构造函数。

我们就可以接收一个传递过来的参数了,当然我们要事先进行声明

动态列表 ListView.builder()

 body: new ListView.builder(
          itemCount: items.length,
          itemBuilder: (context,index){
            return new ListTile(
              title: new Text('${items[index]}'),
            );
          },
        ),

必填参数:

  • itemCount:列表行数
  • itemBuilder:内容绘制

当然还有很多可用参数:

  • scrollDirection:滚动方向
  • reverse:是否倒序

等等还有很多,等待大家使用,我这就不多介绍了

转载自:https://juejin.cn/post/6844903876227760141
评论
请登录