flutter常用组件

一、自定义组件

在Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidgetStatefulWidget

StatelessWidget: 无状态组件,状态不可变的widget
StatefulWidget: 有状态组件,持有的状态可能在widget 生命周期改变

import 'package:flutter/material.dart';
void main(){
	runApp(MyApp());
}
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        // TODO: implement build
        return Center(
            child: Text(
            	"我是一个文本内容",
            	textDirection: TextDirection.ltr,  // 文字方向
                // 文字样式
            	style: TextStyle(
                    fontSize: 40.0,
                    fontWeight: FontWeight.bold,
                    // color: Colors.yellow
                    color: Color.fromRGBO(255, 222, 222, 0.5)
                ),
            ),
        );
    }
}

二、MaterialApp 和 Scaffold

1、MaterialApp

MaterialApp 是一个方便的Widget,它封装了应用程序实现 Material Design 所需要的一些Widget。一般作为顶层widget 使用。

常用的属性:
home(主页)
title(标题)
color(颜色)
theme(主题)
routes(路由)

2、Scaffold

Scaffold 是Material Design 布局结构的基本实现。此类提供了用于显示drawer、snackbar 和底部 sheet 的API。

Scaffold 有下面几个主要属性:
appBar - 显示在界面顶部的一个AppBar。
body - 当前界面所显示的主要内容Widget。
drawer - 抽屉菜单控件。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return MaterialApp(
      title: "我是一个标题",
      home: Scaffold(
        appBar: AppBar(
          title: Text('IT 营'),
          elevation: 30.0, //设置标题阴影不需要的话值设置成0.0
        ),
        body: MyHome(),
      ),
      theme: ThemeData(
          // 设置主题颜色
          primarySwatch: Colors.yellow),
    );
  }
}

class MyHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return Center(
      child: Text(
        "我是Dart 一个文本内容",
        textDirection: TextDirection.ltr,
        style: TextStyle(
            fontSize: 40.0, fontWeight: FontWeight.bold, color: Colors.black38
			// color: Color.fromRGBO(255, 222, 222, 0.5)
            ),
      ),
    );
    ;
  }
}

三、Container 组件、Text 组件

1、Text 组件

属性功能
textAlign文本对齐方式(center 居中,left 左对齐,right 右对齐,justfy 两端对齐)
textDirection文本方向(ltr 从左至右,rtl 从右至左)
overflow文字超出屏幕之后的处理方式(clip 裁剪,fade 渐隐,ellipsis 省略号)
textScaleFactor字体显示倍率
maxLines文字显示最大行数
style字体的样式设置

TextStyle 常用参数:

属性功能
decoration文字装饰线(none 没有线,lineThrough 删除线,overline 上划线,underline 下划线)
decorationColor文字装饰线颜色
decorationStyle文字装饰线风格([dashed,dotted] 虚线,double 两根线,solid 一根实线,wavy 波浪线)
wordSpacing单词间隙(如果是负值,会让单词变得更紧凑)
letterSpacing字母间隙(如果是负值,会让字母变得更紧凑)
fontStyle文字样式(italic 斜体,normal 正常体)
fontSize文字大小
color文字颜色
fontWeight字体粗细(bold 粗体,normal 正常体)

2、Container 组件

属性功能
alignmenttopCenter:顶部居中对齐
topLeft:顶部左对齐
topRight:顶部右对齐
center:水平垂直居中对齐
centerLeft:垂直居中水平居左对齐
centerRight:垂直居中水平居右对齐
bottomCenter 底部居中对齐
bottomLeft:底部居左对齐
bottomRight:底部居右对齐
marginmargin 属性是表示Container 与外部其他组件的距离。
margin: EdgeInsets.all(20.0)
paddingpadding 就是Container 的内边距, 指Container 边缘与Child 之间的距离
padding: EdgeInsets.all(10.0)
transform让Container 进行一些旋转之类的
transform: Matrix4.rotationZ(0.2)
height容器高度
width容器宽度
child容器子元素
decoration组件样式
decoration: BoxDecoration(
  color: Colors.blue,
  // 边框样式
  border: Border.all(
    color: Colors.red,
    width: 2.0,
  ),
  // 边框圆角
  borderRadius:
    BorderRadius.all(
      Radius.circular(8.0)
    )
)

四、图片组件

1、Image 组件

图片组件是显示图像的组件,Image 组件有很多构造函数,这里例举两个:
Image.asset, 本地图片
Image.network 远程图片

Image 组件的常用属性:

属性名类型说明
alignmentAlignment图片的对齐方式
color 和
colorBlendMode
设置图片的背景颜色,通常和colorBlendMode 配合一起使用,这样可以使图片颜色和背景色混合。
fitBoxFitfit 属性用来控制图片的拉伸和挤压,这都是根据父容器来的。
BoxFit.fill: 全图显示,图片会被拉伸,并充满父容器。
BoxFit.contain: 全图显示,显示原比例,可能会有空隙。
BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。
BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。
BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。
BoxFit.scaleDown:效果和contain 差不多,但是此属性不允许显示超过源图片大小,可小不可大。
repeatImageRepeatImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。
ImageRepeat.repeatX: 横向重复,纵向不重复。
ImageRepeat.repeatY:纵向重复,横向不重复。
width宽度 一般结合ClipOval 才能看到效果
height高度 一般结合ClipOval 才能看到效果
return Center(
  child: Container(
    child: Image.network(
        "http://pic.baike.soso.com/p/20130828/20130828161137-1346445960.jpg",
        alignment: Alignment.topLeft,
        color: Colors.red,
        colorBlendMode: BlendMode.colorDodge,
        // repeat: ImageRepeat.repeatX,
        fit: BoxFit.cover,
      ),
    width: 300.0,
    height: 400.0,
    decoration: BoxDecoration(
      color: Colors.yellow
    ),
  ),
);

2、引入本地图片

图片组件

然后,打开 pubspec.yaml 声明一下添加的图片文件

图片组件2

代码中使用

child: Container(
  child: Image.asset("images/a.jpeg",
    fit:BoxFit.cover
  ),
  width: 300.0,
  height: 300.0,
  decoration: BoxDecoration(
    color: Colors.yellow
  ),
)

3、实现圆角图片

child: Container(
    width: 300.0,
    height: 300.0,
    decoration: BoxDecoration(
        color: Colors.yellow,
        borderRadius: BorderRadius.circular(20),
        image: DecorationImage(
            image: NetworkImage("http://pic.baike.soso.com/p/20130828/20130828161137-1346445960.jpg"),
            fit: BoxFit.cover
        )
    ),
),

4、实现圆形图片

Center(
    child: ClipOval(
        child: Image.network(
            "https://www.itying.com/images/201905/thumb_img/1101_thumb_G_1557845381862.jpg",
            width: 150.0,
            height: 150.0,
        ),
    )),

五、列表组件

列表布局是我们项目开发中最常用的一种布局方式。Flutter 中我们可以通过 ListView 来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。

列表有以下分类:
1、垂直列表
2、垂直图文列表
3、水平列表
4、动态列表
5、矩阵式列表

1、ListView 组件

属性类型说明
scrollDirectionAxisAxis.horizontal 水平列表
Axis.vertical 垂直列表
paddingEdgeInsetsGeometry内边距
resolvebool组件反向排序
childrenList列表元素
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return Center(
      child: ListView(
        children: <Widget>[
          ListTile(
            leading: Icon(Icons.phone),
            title: Text(
              "this is list",
              style: TextStyle(fontSize: 28.0),
            ),
            subtitle: Text('this is list this is list'),
          ),
          ListTile(
            title: Text("this is list"),
            subtitle: Text('this is list this is list'),
            trailing: Icon(Icons.phone),
          ),
          ListTile(
            title: Text("this is list"),
            subtitle: Text('this is list this is list'),
          )
        ],
      ),
    );
  }
}

水平列表

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return Container(
        height: 200.0,
        margin: EdgeInsets.all(5),
        child: ListView(
          scrollDirection: Axis.horizontal,  // 定义水平列表
          children: <Widget>[
            Container(
              width: 180.0,
              color: Colors.lightBlue,
            ),
            Container(
              width: 180.0,
              color: Colors.amber,
              child: ListView(
                children: <Widget>[
                  Image.network(
                      'https://resources.ninghao.org/images/childhood-in-a-picture.jpg'),
                  SizedBox(height: 16.0),
                  Text(
                    '这是一个文本信息',
                    textAlign: TextAlign.center,
                    style: TextStyle(fontSize: 16.0),
                  )
                ],
              ),
            ),
            Container(
              width: 180.0,
              color: Colors.deepOrange,
            ),
            Container(
              width: 180.0,
              color: Colors.deepPurpleAccent,
            ),
          ],
        ));
  }
}

动态列表(动态循环数据)

class HomeContent extends StatelessWidget {
  List list = new List();
  HomeContent({Key key}) : super(key: key) {
    for (var i = 0; i < 20; i++) {
      list.add("这是第${i}条数据");
    }
    print(list);
  }
  @override
  Widget build(BuildContext context) {
    return ListView.builder(  // 定义动态列表
      itemCount: this.list.length,
      itemBuilder: (context, index) {
// print(context);
        return ListTile(
          leading: Icon(Icons.phone),
          title: Text("${list[index]}"),
        );
      },
    );
  }
}

2、GridView 组件

GridView 创建网格列表有多种方式,主要介绍两种:

1、可以通过GridView.count 实现网格布局
2、通过GridView.builder 实现网格布局

常用属性:

名称类型说明
scrollDirectionAxis滚动方向
paddingEdgeInsetsGeometry内边距
resolvebool组件反向排序
crossAxisSpacingdouble水平子Widget 之间间距
mainAxisSpacingdouble垂直子Widget 之间间距
crossAxisCountint一行的Widget 数量
childAspectRatiodouble子Widget 宽高比例
children[ ]子元素
gridDelegateSliverGridDelegateWithFixedCrossAxisCount(常用)
SliverGridDelegateWithMaxCrossAxisExtent
控制布局,主要用在GridView.builder 里面

GridView.count 实现网格布局:

class LayoutContent extends StatelessWidget {
  List<Widget> _getListData() {
    var tempList = listData.map((value) {
      return Container(
        child: Column(
          children: <Widget>[
            Image.network(value["imageUrl"]),
            SizedBox(height: 12),
            Text(value["title"],
                textAlign: TextAlign.center, style: TextStyle(fontSize: 20)),
          ],
        ),
        decoration: BoxDecoration(
            border: Border.all(
                color: Color.fromRGBO(230, 230, 230, 0.9), width: 1.0)),
      );
    });
// ('124124','124214')
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return GridView.count(
      padding: EdgeInsets.all(20),
      crossAxisCount: 2,
      crossAxisSpacing: 20,
      mainAxisSpacing: 20,
// childAspectRatio:0.7,
      children: this._getListData(),
    );
  }
}

GridView.builder 实现网格布局:

class LayoutContent extends StatelessWidget {
  Widget _getListData(context, index) {
    return Container(
      child: Column(
        children: <Widget>[
          Image.network(listData[index]["imageUrl"]),
          SizedBox(height: 12),
          Text(listData[index]["title"],
              textAlign: TextAlign.center, style: TextStyle(fontSize: 20)),
        ],
      ),
      decoration: BoxDecoration(
          border: Border.all(
              color: Color.fromRGBO(230, 230, 230, 0.9), width: 1.0)),
    );
  }

  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return GridView.builder(
      itemCount: listData.length,
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
          crossAxisCount: 2,
//纵轴间距
          mainAxisSpacing: 20.0,
//横轴间距
          crossAxisSpacing: 10.0,
//子组件宽高长度比例
          childAspectRatio: 1.0),
      itemBuilder: this._getListData,
    );
  }
}

六、StatefulWidget 有状态组件

  • 在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget / StatefulWidget。
  • StatelessWidget 是无状态组件,状态不可变的 widget
  • StatefulWidget 是有状态组件,持有的状态可能在 widget 生命周期改变。
  • 通俗的讲:如果我们想改变页面中的数据的话这个时候就需要用到 StatefulWidget
class HomePage extends StatefulWidget {
  //Flutter2.2.0之后需要注意把Key改为可空类型  {Key? key} 表示Key为可空类型
  HomePage({Key? key}) : super(key: key);

  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  List list=[];
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Column(
          children: this.list.map((value){
            return ListTile(
              title: Text(value),
            );
          }).toList()
        ),
        SizedBox(height: 20),
        //Flutter2.x以后可以使用ElevatedButton替代RaisedButton也可以继续使用RaisedButton
        ElevatedButton(
          child: Text("按钮"),
          onPressed: (){
            // 通过 setState 方法改变状态
            setState(() {
                this.list.add('新增数据1');
                this.list.add('新增数据2');
            });
          },
        )
      ],
    );
  }
}

七、BottomNavigationBar 自定义底部导航条

BottomNavigationBar 是底部导航条,可以让我们定义底部 Tab 切换,BottomNavigationBar 是 Scaffold 组件的参数。

BottomNavigationBar 常见的属性:

属性说明
itemsList 底部导航条按钮集合
iconSizeicon 大小
currentIndex默认选中第几个
onTap选中变化回调函数
fixedColor选中的颜色
typeBottomNavigationBarType.fixed
BottomNavigationBarType.shifting
Scaffold(
    appBar: AppBar(
        title: Text('Flutter Demo')
    ),
    body: this._pagesList[this._curentIndex],  // 通过改变值实现页面切换
    bottomNavigationBar: BottomNavigationBar(
        currentIndex: _curentIndex,
        onTap: _changePage,
        fixedColor: Colors.black,
        type: BottomNavigationBarType.fixed,
        items: [
            BottomNavigationBarItem(
                title:Text("首页"),
                icon:Icon(Icons.home)
            ),
            BottomNavigationBarItem(
                title:Text("分类"),
                icon:Icon(Icons.category)
            ),
            BottomNavigationBarItem(
                title:Text("设置"),
                icon:Icon(Icons.settings)
            ),
        ],
    ),
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值