flutter-尝鲜篇、快捷键

540 阅读7分钟

前言

这篇文章主要是尝鲜篇章,从创建一个App开始,将一些常见控件调试布局导入文件

开发中我们一般使用 Android Studio(也可以使用 vscode),主要是方便提示

先说一下里面常用的几个快捷键

文件内搜索: command + f

替换: command + r

全局搜索: command + shift + f

修复导入报错(引入文件): option + enter + enter(option + enter 会提示导入的信息,两次enter 就默认第一个)

折叠/展开代码块(推荐)command + .

折叠代码块: command + -

展开代码块: command + +

格式化代码: command + option + l(规范代码格式)

快速生成构造方法: ctl + enter(android studio中,鼠标点击一下类名,摁快捷键,然后选择Constructor,可以快速构建无参或带参构造方法)

去除 Android Studo 的双击弹窗搜索(个人感觉这个比较烦人)

1、Ctrl + Shift + A打开全局搜索

2、搜索registry

3、勾选 ide.suppress.double.click.handler(有顺序的,中间靠下一点位置)

类似于GitHub的flutter仓库地址

尝鲜demo地址(内容在demo文件夹中,可以替换main注释尝试)

flexBox盒式布局----可以作为参考理解盒式布局

注意:如果运行过程中出现了 dart等版本问题可以到 pubspec.yaml文件中,根据错误提示,更改版本号区间,然后修复即可

flutter编辑器以及运行介绍

使用android studio(推荐)

直接右上角选择模拟器,点击运行即可,更改完成之后,切换到模拟器,会自动刷新当前UI,可以理解热重载,调试非常方便(如果切换不自动刷新, cmd + |刷新,cmd + shift + | 重启)

image.png

注意:在平时使用过程中,最不适应的快捷键可能就是,代码整体左移、右移了,在很多编辑器都是 command + [command + ],而studio中为 Tabshift + Tab

我们只需要进入:偏好 -> Keymap -> 搜索 indent,然后更改下面快捷键即可(这也是没把这个快捷键写到前面的原因)

image.png

对于开发过程中的代码缩进问题,调整编辑器不行,只能通过末尾加逗号(,)的方式来统一缩进,例如下面

children: [
  ListView.builder(
    itemBuilder: itemForRow,
    itemCount: friends.length,
  ),
  Positioned(
    child: ContactIndexs(
      letterList: letters,
    ),
  ), //这里一定要加逗号,不然里面一层首行缩进会有问题,每一层都同理
],//这里一定要加逗号,不然里面一层首行缩进会有问题,每一层都同理

vscode

当然可能有人用不惯 Android Studio,用 vscode也照样能开发

vscode没有了选择模拟器的按钮,可以打开终端,使用下面命令打开模拟器,以ios为例(android模拟器个人感觉太丑,可以自行去尝试😂)

flutter run -d 'iPod touch'

会觉得 iPod touch名字怎么出来的,打开模拟器后,可以右键查看名字,也可以自己切换

image.png

而更改内容后,刷新界面(热重载),需要切换到运行终端,按 r键即可,如果想重新运行 R(shift + r)

image.png

flutter尝鲜

我们就从main函数开始,先加入一个 hello world

使用前,需要导入(import)一个UI框架 material,其就像 UIKit框架一样,导入后方可使用系统的UI布局

//导入文件
import 'package:flutter/material.dart';

main函数左右项目的开始,可以直接给定一个 Widget类型的 class

void main() => runApp(const MyWidge());

如果所示,定义个class继承中StatelessWidget,其默认最小的状态类,一般继承自这个,下面编写一个局中的 的文本Text,下面的 Text 编写方式可以参考,TextAlign一看就是对其方式,你可以试试android的对其单词,都一样

由于就只有中间一行字就不展示图片了

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

  @override
  Widget build(BuildContext context) {
    //可以使用这个变量,定义 TextStyle,可以直接引用,或者复用
    const textStyle = TextStyle(
        color: Colors.green,
        fontSize: 32,
        fontWeight: FontWeight.bold
    );
    
    //center为局中字段,里面的View,默认会局中放置
    return const Center(
        child: Text("hello world!",
          textAlign: TextAlign.center,
          style: TextStyle( //可以在前面声明直接使用变量
              color: Colors.blue,
              fontSize: 36,
              fontWeight: FontWeight.bold
          ),
        )
    );
  }
}

hello world 案例

下面给添加一下最常见的 navigation导航tabbar

下面建 helloworld的类 MyApp重命名成 MyWidge,在MyApp类中编写导航相关

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

  @override
  Widget build(BuildContext context) {
    //MeterialApp是我们编写常见的app要用的设计类
    return MaterialApp(
      title: "FlutterDemo", //设计的标题名字,不是导航显示的
      //Scaffold则是我们加入导航要用的类
      home: Scaffold(
        //appBar属性就是我们的导航了,可以设置标题,颜色,左视图,右视图
        appBar: AppBar(
          backgroundColor: Colors.blue,
          foregroundColor: Colors.white,
          title: const Text('hello word!'),
          左右两边视图可以尝试leading、actions参数尝试呀
        ),
        //底部tabbar就不多说了吧,自定义即可
        //bottomNavigationBar: Text("我是底部Tabbar"),
        //就是导航下面的内容部分,介于navigation和tabbar中间那部分
        body: const MyWidge() //给helloworld的类 MyApp重命名成 MyWidge
      )
    );
  }
}

加入导航后,效果如下所示,看起来还不错,有点雏形了

image.png

Container案例

下面介绍一下 Container 的介绍案例,其有点像 UIView 或者 div,是一个基础类,能干不少事情,即能占位,又能控制内部布局(设置内部对齐方式,非常常用),如下所示

另外,下面页测试了一个 Column的案例为垂直方向盒式布局Row则是 水平方向,通过他们可以布局出各种形式的UI

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

  @override
  Widget build(BuildContext context) {
    //container可以理为UIView,有点像div,可以作为背景,设置颜色,内部布局,对齐方式等
    return Container(
      color: Colors.white,
      child: Column( //默认为垂直方向布局, Row为水平方向布局
        mainAxisAlignment: MainAxisAlignment.start,//主方向默认布局方式(垂直)
        crossAxisAlignment: CrossAxisAlignment.start, //副方向(水平)
        children: <Widget>[
          //container也可以像text一样放置东西,可以调整间距等
          Container(
            width: 200,
            alignment: Alignment.centerLeft, //可以尝试里面的数据,内容对齐到哪里去
            height: 100,
            child: const Text('我是第一个Container元素',
            )
          ),
          const Text('我是Text'),
          Container(
              width: 200,
              alignment: Alignment.center,//内容居中
              height: 100,
              child: const Text('我是第二个Container元素')
          )
        ]
      )
    );
  }
}

如下所示,是上面设置的布局效果,可以理解一下

image.png

富文本RichText案例

富文本的案例比较简单,通过嵌套的方式,嵌套组合文本,以形成我么你想要的效果

通过 RichText 打头,不停的通过 TextSpan 来拼接富文本即可

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

  @override
  Widget build(BuildContext context) {
    //外面的Container不是必须的,只是备用,可以用来调整间距的
    return Container(
      alignment: Alignment.topCenter,
      child: RichText(
        text: const TextSpan(
          text: "我是",//也可以不设置Text,后面不设置属性的默认此style
          style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.normal,//默认的可以不用填写
            color: Colors.black12
          ),
          children: <TextSpan>[
            TextSpan(text: '一名'),
            TextSpan(
              text: 'ios',
              style: TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
                color: Colors.red
              )
            ),
            TextSpan(text: '、'),
            TextSpan(
                text: 'flutter',
                style: TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                    color: Colors.yellow
                )
            ),
            TextSpan(text: '开发者')
          ]
        )
      ),
    );
  }
}

如下所示,拼接的简单的富文本案例

image.png

ListView案例

表格视图使我们最常见的视图了,例如我们最常见的 TableView,在这里他叫 ListView, android的相信更不陌生,我们可以通过他来开发垂直方向的图文混排的视图,就像微信朋友圈、聊天一样,都有这种视图身影在里面

如下所示我们,写一个简单的 图文混排的按 ListView案例,其使用的是 ListView.builder

`carsDatas``Car`类型的数组

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

  //可以将row的内容放到这里main
  Widget cellForRow(BuildContext context, int index) {
    return Container();
  }

  @override
  Widget build(BuildContext context) {
    //想控制ListView的内间距或者外间距,可以尝试嵌套 Container
    return ListView.builder(
        itemCount: carsDatas.length,
        // itemBuilder: cellForRow, //可以指向外部方法
        itemBuilder: (BuildContext context, int index) {
          return Column(
            children: <Widget>[
              // Container(
              //   width: 300,
              //   height: 100,
              //   child: Image.network(carsDatas[index].imageUrl,
              //     fit: BoxFit.fitWidth, 当外部有container的时候,可以设置填充方式,默认平铺
              //   ),
              // ),
              //网络加载图片,没有本地缓存
              Image.network(carsDatas[index].imageUrl,
                fit: BoxFit.fitWidth,
              ),
              Container(height: 8),
              Text(carsDatas[index].name),
              Container(height: 8)
            ],
          );
        }
    );
  }
}

car的属性如下所示,carsDatasCar类型的数组

class Car {
  final String name;
  final String imageUrl;
  Car(this.name, this.imageUrl); //const 修饰的对象不能改,只能声明时使用,使用时需要用 const修饰
}

如下所示,是不是很简单呢

image.png

最后

快来尝试一下吧,找到兴趣,我们就可以继续学习后面的布局实战项目