Flutter基础语法

Flutter概要

        

Flutter目录结构

文件夹

作用

android

android 平台相关代码

ios

ios平台相关代码

lib

flutter相关代码,我们主要编写的代码就在这个文件夹中

test

用于存放测试的代码

pubspec.yaml

配置文件,一般存放一些第三方库的依赖

Flutter入口文件、入口方法

        每一个 flutter 项目的 lib 目录里面都有一个 main.dart 这个文件就是 flutter 的入口文件。

main.dart里面

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

         其中的 main 方法是 dart 的入口方法。runApp 方法是 flutter 的入口方法。 MyApp 是自定义的一个组件。

单独的内容抽离成的一个组件

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

前期我们都继承 StatelessWidget。

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

MaterialApp和Scaffold装饰APP

        MaterialApp 是一个方便的 Widget,它封装了应用程序实现 Material Design 所需要的

一些 Widget。一般作为顶层widget 使用。

常用的属性:

  • home(主页)
  • title(标题)
  • color(颜色)
  • theme(主题)
  • routes(路由)
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.red,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

Scaffold 有下面几个主要属性:

  • appBar - 显示在界面顶部的一个 AppBar。
  • body - 当前界面所显示的主要内容 Widget。
  • drawer - 抽屉菜单控件。
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

各类组件

Flutter Container 组件、Text组件

Flutter Container 组件

        

名称

功能

alignment

topCenter:顶部居中对齐

topLeft:顶部左对齐

topRight:顶部右对齐

center:水平垂直居中对齐

centerLeft:垂直居中水平居左对齐

centerRight:垂直居中水平居右对齐 bottomCenter 底部居中对齐

bottomLeft:底部居左对齐

bottomRight:底部居右对齐

decoration

decoration: BoxDecoration( color: Colors.blue, border: Border.all( color: Colors.red, width: 2.0, ), borderRadius: BorderRadius.all( Radius.circular(8.0) )

)

margin

margin 属性是表示 Container 与外部其他 组件的距离。 EdgeInsets.all(20.0),

padding

padding 就是 Container 的内边距,指 Container 边缘与 Child 之间的距离 padding: EdgeInsets.all(10.0)

transform

让 Container 容易进行一些旋转之类

transform: Matrix4.rotationZ(0.2)

height

容器高度

width

容器宽度

child

容器子元素

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("Flutter Demo"),
        ),
        body: BodyConent(),
      ),
    );
  }
    

  }

  // 内容组件
  class BodyConent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(              
      //child 容器元素
      child:Text("欢迎来到Flutter"),
      // 装饰
      // 背景 颜色浅蓝色
      decoration: BoxDecoration(color: Color.fromRGBO(100, 233, 244, 0.5), 
      // 圆角
      borderRadius: BorderRadius.all(Radius.circular(10.0))), 
      // 对齐方式
      alignment: Alignment.center,
      width: 300.0 ,
      height: 300.0,
      ),
    );

  }

  }

Flutter 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 正常体)

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("Flutter Demo"),
        ),
        body: BodyConent(),
      ),
    );
  }
    

  }

  // 内容组件
  class BodyConent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    var text = Text(
      "欢迎来到Flutter开发学习",
      // 对齐方式-居中
      textAlign: TextAlign.center,
      // 文字超出处理 ...
      overflow: TextOverflow.ellipsis,
      // 字体放大
      textScaleFactor: 2.0,
      // 具体样式
      style: TextStyle(
        // 下划线
        decoration:TextDecoration.underline,
        // 单词界限
        wordSpacing: 3.0,
        // 文字颜色
        color:Color.fromRGBO(255, 255, 255, 2) ,
         ),
        
    );
    return Center(
      child: Container(              
      //child 容器元素
      child:text,
      // 装饰
      // 背景 颜色浅蓝色
      decoration: BoxDecoration(color: Color.fromRGBO(100, 233, 244, 0.5), 
      // 圆角
      borderRadius: BorderRadius.all(Radius.circular(10.0))), 
      // 对齐方式
      alignment: Alignment.center,
      width: 300.0 ,
      height: 300.0,
      ),
    );

  }

  }

图片组件 

        

        图片组件是显示图像的组件,Image 组件有很多构造函数。

        Image.asset, 本地图片

        Image.network 远程图片

名称

类型

说明

alignment

Alignment

图片对齐方式

color | colorBlendMode

设置图片的背景颜色,通常和 colorBlendMode 配合一起 使用,这样可以是图片颜色和背景色混合。上面的图片就 是进行了颜色的混合,绿色背景和图片红色的混合

fit

BoxFit

fit 属性用来控制图片的拉伸和挤压,这都是根据父容器来 的。 BoxFit.fill:全图显示,图片会被拉伸,并充满父容器。

BoxFit.contain:全图显示,显示原比例,可能会有空隙。

BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要 充满整个容器,还不变形)

BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸, 可能裁切。

BoxFit.fitHeight :高度充满(竖向充满),显示可能拉 伸,可能裁切。

BoxFit.scaleDown:效果和 contain 差不多,但是此属 性不允许显示超过源图片大小,可小不可大

repeat

平铺

ImageRepeat.repeat: 横向和纵向都进行重复,直到铺满整 个画布。 ImageRepeat.repeatX: 横向重复,纵向不重复。

ImageRepeat.repeatY:纵向重复,横向不重复

width

宽度 一般结合 ClipOval 才能看到效果

height

高度 一般结合 ClipOval 才能看到效果

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("Flutter Demo"),
        ),
        body: BodyConent(),
      ),
    );
  }
    

  }

  // 内容组件
  class BodyConent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(              
      //child 容器元素
      // 装饰
      // 背景 颜色浅蓝色
      decoration: BoxDecoration(
        color: Color.fromRGBO(100, 233, 244, 0.5), 
        // 图片组件-网络图片
        image: DecorationImage(image: NetworkImage('https:\/\/www.logosc.cn\/uploads\/resources\/2023\/03\/17\/1679044779.jpg'),
        // 全图显示
        fit: BoxFit.fill),
        
      // 圆角
      borderRadius: BorderRadius.all(Radius.circular(10.0))), 
      // 对齐方式
      alignment: Alignment.center,
      width: 300.0 ,
      height: 300.0,
      ),
    );

  }

  }

本地引入图片

1、根目录新建images文件夹

2、pubspec.yaml 配置路径

Flutter ListView 组件

        

    列表布局是我们项目开发中最常用的一种布局方式。

    Flutter 中我们可以通过 ListView 来定义 列表项,支持垂直和水平方向展示。

   通过一个属性就可以控制列表的显示方向。

   列表有以下分类:

  •  垂直列表
  • 垂直图文列表
  • 水平列表
  • 动态列表
  • 矩阵式列表

名称

类型

说明

scrollDirection

Axis

Axis.horizontal 水平列表 Axis.vertical 垂直列表

padding

EdgeInsetsGeometry

内边距

resolve

bool

组件反向排序

children

List<Widget>

列表元素

 基本列表

class ListContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
   
    return Container(
      child:ListView(children: [
          ListTile(
          leading: Icon(Icons.smart_button),
          title: Text("愿人平安幸福如意"),
        ),
        ListTile(
          leading: Icon(Icons.ac_unit_sharp),
          title: Text("生活如意,事事顺心"),
        ),
        ListTile(
          leading: Icon(Icons.ac_unit_sharp),
          title: Text("时来运转,好运连连"),
        ),
                ListTile(
          leading: Icon(Icons.access_time_sharp),
          title: Text("心想事成,梦想成真"),
        ),
                ListTile(
          leading: Icon(Icons.access_alarm_outlined),
          title: Text("世界和平,人心安宁"),
        ),
                ListTile(
          leading: Icon(Icons.access_alarm),
          title: Text("爱与和谐,家庭美满"),
        ),
                ListTile(
          leading: Icon(Icons.ac_unit_outlined),
          title: Text("健康长寿,幸福美好"),
        ),
      ],
      )
    );
  }

}

水平列表

        

class ListContent1 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    
    return Container(
      height: 200.0,
      margin: EdgeInsets.all(5),
      child: ListView(
        // 水平列表
        scrollDirection: Axis.horizontal ,
        children:<Widget> [
          Container(
            width: 150.0,
            color: Colors.lightBlue,
          ),
          Container(
            width: 180.0,
            color: Colors.amber,
            child: ListView(
              children:  <Widget> [
                Image.network("https:\/\/www.logosc.cn\/uploads\/resources\/2023\/03\/17\/1679044779.jpg"),
                SizedBox(height:16.0), 
                Text('风景很美~', textAlign:TextAlign.center, style:TextStyle( fontSize:16.0 ), ) 
              ],
              
            ),
          ),
          Container(
            width: 150.0,
            color: Colors.black,
          )

        ],

      ),
    
    );
    
  }

}

动态列表 

// 列表-动态组件
class ListDynamic extends StatelessWidget{

  List content_list = [];
  ListDynamic({key}):super(key: key){
    for(var i=0; i<20; i++){
      content_list.add("这是第$i条数据");
    }
  }
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: this.content_list.length,
      itemBuilder: (context, index){
        return ListTile(
          leading: Icon(Icons.ac_unit),
          title: Text("${content_list[index]}"),
        );
      },
    );

    
  }

}

 Flutter GridView 组件

        当数据量很大的时候用矩阵方式排列比较清晰。此时我们可以用网格列表组件 GridView 实现布局。

GridView 创建网格列表有多种方式,下面我们主要介绍两种。

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

2、通过 GridView.builder 实现网格布局

名称

类型

说明

scrollDirection

Axis

滚动方法

padding

EdgeInsetsGeometry

内边距

resolve

bool

组件反向排序

crossAxisSpacing

double

水平子Widget之间间距

mainAxisSpacing

double

垂直Widget之间间距

crossAxisCount

int

一行的Widget数量

childAspectRatio

double

子 Widget 宽高比例

children

<Widget>[ ]

gridDelegate

SliverGridDelegateWithFix edCrossAxisCount(常用) SliverGridDelegateWithMax CrossAxisExtent

控制布局主要用在 GridView.builder 里面

FlutterGridView.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,
          )
        ],
      ),
      decoration: BoxDecoration(border: Border.all(color: Colors.amber)),
    );

    });
    return tempList.toList();
  }


  @override
  Widget build(BuildContext context) {
    return GridView.count(
      // 列数3
      crossAxisCount:2,
      // 垂直间距
      mainAxisSpacing: 2.0 ,
      // 水平间距
      crossAxisSpacing: 3.0,
      children:this._getListData(),
    );
    
  }

}

FlutterGridView.builder 实现网格布局

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,
          )
        ],
      ),
      decoration: BoxDecoration(border: Border.all(color: Colors.amber)),
    );

    });
    return tempList.toList();
  }


  @override
  Widget build(BuildContext context) {
    return GridView.count(
      // 列数3
      crossAxisCount:2,
      // 垂直间距
      mainAxisSpacing: 2.0 ,
      // 水平间距
      crossAxisSpacing: 3.0,
      children:this._getListData(),
    );
    
  }

}

PaddiingRowColumn Expanded 页面布局

        在 html 中常见的布局标签都有 padding 属性,但是 Flutter 中很多 Widget 是没有 padding 属 性。这个时候我们可以用 Padding 组件处理容器与子元素直接的间距。

class PaddingContent extends StatelessWidget{

  // 返回列表
  List <Widget> _getDate(){
    var tempList = listData.map((value){
      return Padding(
        padding: EdgeInsets.fromLTRB(0, 10, 10, 0),
        child: Image.network(value["imageUrl"],fit: BoxFit.cover),
      );
    });

    return tempList.toList();

  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
        // 两列显示
      crossAxisCount: 2,
      children: this._getDate(),
    );
  }

}

FlutterRow 布局组件 

        

属性

说明

mainAxiAlignment

主轴的排序方式

crossAxiAlignment

次轴的排序方式

children

组件子元素

水平布局Row

class IconContainer extends StatelessWidget{

  double size;
  IconData icon;
  Color color;

  IconContainer(this.icon,{this.size=32.0, this.color=Colors.red});

  @override
  Widget build(BuildContext context) {

  return Container(
    width: this.size+60,
    height: this.size+60,
    color: this.color,
    child: Center(child: Icon(this.icon, color: this.color, size: this.size,)),
);
  }
}


class RowContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
   return Container(
    height: 800,
    width: 600,
    color:  Colors.black26,
    child: Row(
      // 水平对齐方式-居中
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
          IconContainer(Icons.home, color: Colors.red),
          IconContainer(Icons.search, color: Colors.blue),
          IconContainer(Icons.send, color: Colors.orange),
      ],
    ),
   );
  }

}

垂直布局Column

        

属性

说明

mainAxisAlignment

主轴的排序方式

crossAxisAlignment

次轴的排序方式

children

组件子元素

class IconContainer1 extends StatelessWidget{
  double size=32.0;
  Color color=Colors.red;
  IconData icon;
  IconContainer1(this.icon,{this.color,this.size});
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      height: 100.0,
      width: 100.0,
      color: this.color,
      child: Center(
        child: Icon(this.icon,size: this.size,color: Colors.white)
      ),
    );
  }
}

class CloumnContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {

    return Container(
      width: 500,
      height: 400,
      child: Column(
        // 垂直布局
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children:<Widget> [
          IconContainer1(Icons.search,color: Colors.blue),
          IconContainer1(Icons.home,color: Colors.orange),
          IconContainer1(Icons.select_all,color: Colors.red),
        ],
      ),
    );
  }
  
}

Row和Column结合

        FlutterExpanded类似Web中的Flex 布局

        Expanded 可以用在 Row 和 Column 布局中

属性

说明

flex

元素占整个父Row/Colum的比例

child

子元素

class LayoutContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(10),
      child: Row(mainAxisAlignment:MainAxisAlignment.center,
        children: <Widget>[
          Expanded(flex:2,child:IconContainer(Icons.home)), 
          SizedBox(width:10), 
          Expanded(flex:3,child:IconContainer(Icons.search)),
        ],
      
      ),
    );
  }

}

class IconContainer extends StatelessWidget {
  double size;
  IconData icon;
  Color color;

  IconContainer(this.icon, {this.size =32.0, this.color = Colors.blue});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
        width: this.size + 60,
        height: this.size + 60,
        color: this.color,
        child: Center(
            child: Icon(this.icon, color: Colors.white, size: this.size)));
  }
}

Flutter Stack 层叠组件 

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

属性

说明

alignment

配置所有子元素的显示位置

children

子组件

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("Flutter Demo")),
        body: LayOutContent(),),
    );
  }

}

class LayOutContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    
    return Center(
      child: Stack(alignment: Alignment.center,
      children: <Widget>[
          Container(height: 400, width: 400, color: Colors.black),
          Text('我是一个文本',style: TextStyle(fontSize: 30, color: Colors.amber),)
      ],),
    );
  }

}

Stack 组件中结合 Align 组件可以控制每个子元素的显示位置

属性

说明

alignment

配置所有子元素的显示位置

children

子组件

class LayOutContent1 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
   
   return Center(
    child: Container(
      height: 400,
      width: 400,
      color: Colors.amber,
      child: Stack(children: <Widget>[
        Align(alignment: Alignment(1,-1), child: Icon(Icons.ac_unit, size: 40, color: Colors.blue)),
        Align(alignment: Alignment(1,1),child: Icon(Icons.ac_unit,size: 40, color: Colors.brown)),
        Align(alignment: Alignment(-1,1),child: Icon(Icons.ac_unit_sharp,size: 40, color: Colors.red)),
        Align(alignment: Alignment(-1,-1),child: Icon(Icons.ac_unit_sharp,size: 40, color: Colors.black)),

      ],),
    )
   );
    
  }

}

Stack 组件中结合 Positioned 组件也可以控制每个子元素的显示位置。

属性

说明

top

子元素距离顶部的距离

bottom

子元素距离底部的距离

left

子元素距离左侧的距离

right

子元素距离右侧的距离

child

子组件

class LayOutContent1 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
   
   return Center(
    child: Container(
      height: 400,
      width: 400,
      color: Colors.amber,
      child: Stack(children: <Widget>[
        Positioned(child: Icon(Icons.ac_unit, size: 40, color: Colors.blue),top: 10),
        Positioned(child: Icon(Icons.ac_unit, size: 40, color: Colors.brown),top: 60,),
        Positioned(child: Icon(Icons.ac_unit, size: 40, color: Colors.black),top: 110,),
        Positioned(child: Icon(Icons.ac_unit, size: 40, color: Colors.red),top: 160,),

      ],),
    )
   );
    
  }

}

Flutter AspectRatio组件

        AspectRatio 的作用是根据设置调整子元素 child 的宽高比。

        AspectRatio 首先会在布局限制条件允许的范围内尽可能的扩展,widget 的高度是由宽度和比率决定的,类似于 BoxFit 中的 contain,按照固定比率去尽量占满区域。

        如果在满足所有限制条件过后无法找到一个可行的尺寸,AspectRatio 最终将会去优先 适应布局限制条件,而忽略所设置的比率。

属性

说明

aspectRatio

宽高比,最终可能不会根据这个值去布局, 具体则要看综合因素,外层是否允许按照这 种比率进行布局,这只是一个参考值

child

子组件

class LayOutdemo extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    
    return Center(
      child: Container(width: 400,
      child: AspectRatio(aspectRatio: 16.0/9.0, 
      child: Container(color: Colors.black,),),),
    );
  }

}

Flutter Card 组件 

        Card 是卡片组件块,内容可以由大多数类型的 Widget 构成,Card 具有圆角和阴影,这让它 看起来有立体感。

        

属性

说明

margin

外边距

child

子组件

Shape

Card

class LayOutDemoCard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Card(
            margin: EdgeInsets.all(10),
            child: Column(
              children: <Widget>[
                ListTile(
                    title: Text("赵二新", style: TextStyle(fontSize: 28)),
                    subtitle: Text("高级软件工程师")),
              ],
            )),
        Card(
            margin: EdgeInsets.all(10),
            child: Column(
              children: <Widget>[
                ListTile(
                    title: Text("赵三新", style: TextStyle(fontSize: 28)),
                    subtitle: Text("高级软件工程师")),
                Divider(),
              ],
            )),
        Card(
            margin: EdgeInsets.all(10),
            child: Column(
              children: <Widget>[
                ListTile(
                    title: Text("赵四新", style: TextStyle(fontSize: 28)),
                    subtitle: Text("高级软件工程师")),
                Divider(),
              ],
            )),
        Card(
            margin: EdgeInsets.all(10),
            child: Column(
              children: <Widget>[
                ListTile(
                    title: Text("赵五新", style: TextStyle(fontSize: 28)),
                    subtitle: Text("高级软件工程师")),
                Divider(),
              ],
            )),
      ],
    );
  }
}

 Flutter 页面布局 Wrap 组件

 RaiseButton组件

        Flutter 中通过 RaisedButton 定义一个按钮。RaisedButton 里面有很多的参数,这里只展示简单的例子。


class LayoutButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: RaisedButton(child: Text("点击"),textColor:Theme.of(context).accentColor,onPressed:(){}),
    );

  }
}

Wrap 组件 

        Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Row 表 现几乎一致。但 Row 与 Column 都是单行单列的,Wrap 则突破了这个限制,mainAxis 上空 间不足时,则向 crossAxis 上去扩展显示。

属性

说明

direction

主轴说明,默认水平

alignment

主轴的对齐方向

spacing

主轴方向上的间距

textDirection

文本方向

verticalDirection

定义了 children 摆放顺序,默认是 down,见 Flex 相关属性介绍。

runAlignment

run 的对齐方式。run 可以理解为新的行或者 列,如果是水平方向布局的话, run 可以理解 为新的一行

runSpacing

run 的间距

class MyButton extends StatelessWidget{

  final String text;
  const MyButton(this.text,{key}):super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text(this.text),
      onPressed: (){

      },
    );
  }

}


class LayoutButtonContent extends StatelessWidget{

  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 10,
      runSpacing: 10,
      alignment: WrapAlignment.spaceEvenly,
      children: <Widget>[
        MyButton("第一集"),
        MyButton("第二集"),
        MyButton("第三集"),
        MyButton("第四集"),
        MyButton("第五集"),
        MyButton("第六集"),
        MyButton("第七集"),
        MyButton("第八集"),
        MyButton("第九集"),
        MyButton("第十集"),
        MyButton("第十一集"),
      ],
    );
  }

}

Flutter StatefulWidget 组件 

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

StatelessWidget 是无状态组件,状态不可变的 widget

        StatefulWidget 是有状态组件,持有的状态可能在 widget 生命周期改变。

        通俗的讲:如果我们想改变页面中的数据的话这个时候就需要用到 StatefulWidget


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("有状态的组件")),
        body: HomePage()),
    );
  }

}

class HomePage extends StatefulWidget{

  HomePage({Key key}):super(key: key);

  _HomePageState createState()=> _HomePageState();
}

class _HomePageState extends State<HomePage>{
  int count = 0;
  @override
  Widget build(BuildContext context) {
    
    return Container(
      child: Column(
        children: <Widget>[
          Chip(label: Text("${this.count}")),
          RaisedButton(child: Text("增加"), onPressed: (){
            setState(() {
              this.count++;
            });
          })
        ],
      ),
    );
  }

}

 FlutterBottomNavigationBar

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

属性

说明

items

List<BottomNavigationBarItem> 底部导航 条按钮集合

iconSize

icon

currentIndex

默认选中第几个

fixedColor

选中的颜色

type

BottomNavigationBarType.fixed

BottomNavigationBarType.shifting

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: 
      Scaffold(
        appBar: AppBar(title: Text("有状态的组件")),
        body: HomePage(),
        bottomNavigationBar: BottomNavigationBar(items: [
          BottomNavigationBarItem(title: Text("首页"),icon: Icon(Icons.inbox)),
          BottomNavigationBarItem(title: Text("分类"),icon: Icon(Icons.search_off)),
          BottomNavigationBarItem(title: Text("设置"),icon: Icon(Icons.settings)),
        ],),
        ),
    );
  }

}

Flutter 中路由 

        普通路由、普通路由传值、 命名路由、命名路由传值

        Flutter 中的路由通俗的讲就是页面跳转。

        在 Flutter 中通过 Navigator 组件管理路由导航。 并提供了管理堆栈的方法。

        如:Navigator.push 和 Navigator.pop

        Flutter 中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由

基本路由

        基本路由是一种简单的路由管理方式,通常用于小型应用或简单的导航需求。在基本路由中,您直接使用Navigator类来进行页面之间的切换,通常用Navigator.push来打开新页面,使用Navigator.pop来返回上一页。

        

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirstScreen(),
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('第一个屏幕')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(context, MaterialPageRoute(builder: (context) => SecondScreen()));
          },
          child: Text('打开第二个屏幕'),
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('第二个屏幕')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('返回第一个屏幕'),
        ),
      ),
    );
  }
}

 命名路由

        命名路由是一种更高级的路由管理方式,它允许您为每个页面分配一个唯一的名称,然后通过这些名称来导航到不同的页面。命名路由的优势在于它更适合大型应用,更易于维护和扩展。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      routes: {
        '/': (context) => FirstScreen(),
        '/second': (context) => SecondScreen(),
      },
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('第一个屏幕')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/second');
          },
          child: Text('打开第二个屏幕'),
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('第二个屏幕')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('返回第一个屏幕'),
        ),
      ),
    );
  }
}

Flutter AppBar 自定义顶部导航

        

属性

描述

leading

在标题前显示一个控件,在首页通常显示的Logo,在其他界面通常显示作为返回按钮

title

标题,通常显示为当前界面的标题文字,可以放组件

actions

通常使用IconButton来表示,可以放按钮

bottom

通常放tabBar,标题下面显示一个Tab导航栏

backgroundColor

导航背景颜色

iconTheme

图标样式

textTheme

文字样式

CenterTitle

标题是否居中显示

// 简单的顶部导航

import 'package:flutter/material.dart';

class AppBardemo extends StatelessWidget {
const AppBardemo({ Key key }) : super(key: key);

  @override
  Widget build(BuildContext context){
    return DefaultTabController(length: 2, 
    child: Scaffold(appBar:  AppBar(title: Text("AppBarDemoPage"),
    centerTitle: true,
    bottom: TabBar(tabs: <Widget>[Tab(text: '热门'), Tab(text: '推荐',)],),
    
    ),
    body: TabBarView(children: <Widget>[
      ListView(
        children:<Widget> [
          ListTile(title: Text("第一个Tab")),
          ListTile(title: Text("第一个Tab")),
          ListTile(title: Text("第一个Tab")),
          
        ],
      ),
            ListView(
        children:<Widget> [
          ListTile(title: Text("第二个Tab")),
          ListTile(title: Text("第二个Tab")),
          ListTile(title: Text("第二个Tab")),
          
        ],
      ),

    ]),
    
    )
    
    
    );
  }
}

Flutter Drawer 侧边栏 

        在 Scaffold 组件里面传入 drawer 参数可以定义左侧边栏,传入 endDrawer 可以定义右侧边 栏。侧边栏默认是隐藏的,我们可以通过手指滑动显示侧边栏,也可以通过点击按钮显示侧 边栏。

Flutter DrawerHeader

        

属性

描述

decoration

设置顶部背景颜色

child

配置子元素

padding

内边距

margin

外边距

import 'package:flutter/material.dart';
import './tabs/Homepage.dart';
import './tabs/Categorypage.dart';
import './tabs/Settingspage.dart';

class Tabs extends StatefulWidget {
  const Tabs({Key key}) : super(key: key);

  @override
  _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  int _currentIndex = 0;
  List _pageList = [Homepage(), Categorypage(), Settingspage()];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter Demo"),
      ),
      drawer: Drawer(child: Column(children: <Widget>[
        DrawerHeader(
          decoration: BoxDecoration(
          color: Colors.yellow,
          image: DecorationImage(
            image: NetworkImage("https://www.itying.com/images/flutter/1.png"),
            fit: BoxFit.cover
          ),
        ),
        child: ListView(
          children: <Widget>[
            Text('我是头部')
          ],
        ),
        ),
        ListTile(
          title: Text("个人中心"),
          leading: CircleAvatar(child: Icon(Icons.people),),
        ),
        Divider(),
        ListTile(
          title: Text("系统设置"),
          leading: CircleAvatar(child: Icon(Icons.settings),),
        )
      ],)),
      body: this._pageList[this._currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: this._currentIndex,
        onTap: (int index) {
          setState(() {
            this._currentIndex = index;
          });
        },
        iconSize: 36.0,
        fixedColor: Colors.red,// 选中的颜色
        type: BottomNavigationBarType.fixed,
        items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              title: Text("首页")
            ),
             BottomNavigationBarItem(
              icon: Icon(Icons.category),
              title: Text("分类")
            ),
            
             BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text("设置")
            )
        ],
      ),
    );
  }
}

Flutter UserAccountsDraweHeader 

        

属性

说明

decoration

设置顶部背景颜色

accountName

账户名称

accountEmail

账户邮箱

currentAccountPicture

用户头像

otherAccountsPictures

用来设置当前用户其它账户头像

import 'package:flutter/material.dart';
import './tabs/Homepage.dart';
import './tabs/Categorypage.dart';
import './tabs/Settingspage.dart';

class Tabs extends StatefulWidget {
  const Tabs({Key key}) : super(key: key);

  @override
  _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  int _currentIndex = 0;
  List _pageList = [Homepage(), Categorypage(), Settingspage()];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter Demo"),
      ),
      endDrawer: Drawer(
          child: Column(
        children: <Widget>[
          UserAccountsDrawerHeader(
            accountName: Text("小王老师"),
            accountEmail: Text("6666@qq.com"),
            currentAccountPicture: CircleAvatar(
              backgroundImage:
                  NetworkImage("https://www.itying.com/images/flutter/1.png"),
            ),
            decoration: BoxDecoration(
                color: Colors.yellow,
                image: DecorationImage(
                    image: NetworkImage(
                        "https://www.itying.com/images/flutter/3.png"),fit: BoxFit.cover)),
          ),
          ListTile(title:  Text("个人中心")),
          Divider(),
          ListTile(title: Text("系统设置"),leading: CircleAvatar(child: Icon(Icons.settings)),),
          
        ],
      )),
      
      body: this._pageList[this._currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: this._currentIndex,
        onTap: (int index) {
          setState(() {
            this._currentIndex = index;
          });
        },
        iconSize: 36.0,
        fixedColor: Colors.red, // 选中的颜色
        type: BottomNavigationBarType.fixed,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
          BottomNavigationBarItem(
              icon: Icon(Icons.category), title: Text("分类")),
          BottomNavigationBarItem(icon: Icon(Icons.settings), title: Text("设置"))
        ],
      ),
    );
  }
}

1、Flutter 和 Dart 的关系是什么?

Flutter 是一个由谷歌开发的开源UI工具包,用于从单一的代码库创建精美的、编译型的移动、Web和桌面应用程序。而 Dart 是由谷歌开发的客户端优化的编程语言,用于快速地提供交互式应用体验。Flutter 使用 Dart 作为其开发语言,Dart 为 Flutter 提供了高性能的运行时和编译器支持,使得 Flutter 应用能够快速运行。

2、Widget 和 element 和 RenderObject 之间的关系?

在 Flutter 中,这三个概念构成了其UI框架的核心。

  • Widget:是 Flutter UI 开发的基础,它描述了UI元素的配置信息。Widget 是不可变的,这意味着它们是不可改变的对象,当它们的状态发生变化时,Flutter 会创建一个新的 Widget 树来替换旧的。
  • Element:是 Widget 的一个实例,它在 Widget 树中保持稳定,即使 Widget 本身被重新构建。Element 对应于 Widget 树中的特定位置,它负责将 Widget 的配置应用到 RenderObject 上。
  • RenderObject:负责实际的布局和绘制操作。每个 RenderObject 对应于一个 Element,并且它们构成了一个渲染树。RenderObject 负责计算布局大小和位置,以及绘制到屏幕上。

3、Flutter 中的 Widget、State、Context 的核心概念?是 为了解决什么问题?

  • Widget:是 Flutter UI 的基本构建块。它描述了UI元素的配置信息,例如按钮、文本、图片等。Widget 是不可变的,这意味着它们是不可改变的对象,这使得 UI 的更新非常高效。
  • State:对于一些需要动态变化的 UI,比如用户交互后的变化,就需要用到 State。State 包含了 Widget 的动态数据,它可以在 Widget 生命周期内发生变化。
  • Context:是 Widget 在 Widget 树中的位置信息。它提供了访问祖先 Widget 的能力,例如获取主题颜色、字体大小等,也用于导航、获取依赖等。

        这些概念的引入是为了解决构建现代UI应用程序的复杂性。通过将 UI 分割成小的、可复用的构建块(Widget),Flutter 使得 UI 的构建和更新变得非常灵活和高效。State 和 Context 的引入则使得 UI 能够响应用户的交互,同时保持代码的可维护性。

4、Widget 的两种类型是什么?

Widget 有两种类型:

  • StatefulWidget:这种 Widget 是动态的,它拥有一个 State 对象,用于保存状态信息。当 State 对象改变时,Widget 会重新构建,从而更新 UI。
  • StatelessWidget:这种 Widget 是静态的,它不保持任何状态信息。当父 Widget 通知它需要重建时,它会根据当前的配置信息重新构建。

5、什么是 Navigator? MaterialApp 做了什么?

  • Navigator:是 Flutter 中的路由管理器,它管理着一堆页面(Route),并提供了一系列方法来推动(push)和弹出(pop)页面,实现页面之间的跳转。

  • MaterialApp:是一个方便的 Widget,它封装了应用程序实现 Material Design 所需的多个 Widget。它提供了应用程序的根 Widget,包括主题(Theme)、路由(Routes)、导航(Navigation)等 Material Design 设计语言的必要支持。使用 MaterialApp 可以快速开始构建符合 Material Design 的应用程序。

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter开发者是指拥有使用Flutter框架进行移动应用开发的技能和经验的人。Flutter是由Google开发的一种跨平台移动应用开发框架,可以用于同时在iOS和Android平台上构建高性能、美观的应用程序。 作为一个Flutter开发者,我具备以下技能和特点: 1. 扎实的Dart编程语言基础Flutter使用Dart作为开发语言,所以熟悉Dart语法和常用库对于开发者来说是必备的。 2. 了解Flutter框架:熟悉Flutter框架的各种组件和功能,能够运用这些组件构建界面、处理用户输入、管理状态等。 3. 跨平台开发能力:Flutter可以实现一次编写,多平台运行,我能够使用Flutter开发跨平台应用,减少了开发周期和成本。 4. UI设计和交互设计能力:通过使用Flutter的强大UI组件库,我可以创建精美的用户界面,并且能够与用户进行良好的交互。 5. 掌握RESTful API集成:在应用中使用Web服务进行数据获取和交互是常见的需求,我具备使用Dart的http库进行RESTful API集成的经验。 6. 熟悉版本控制工具:如Git,能够与团队协作、管理代码库,并且有解决代码冲突和分支管理的经验。 7. 热爱学习和探索新技术:作为一个Flutter开发者,我时刻关注Flutter的最新动态,学习并应用新的技术和框架。 总结来说,作为一个Flutter开发者,我具备扎实的编程基础,熟练掌握Flutter框架和Dart编程语言,能够构建高性能、美观的跨平台移动应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值