今天介绍Flutter如何制作启动页。

这里先看看官方文档介绍启动页时给出的示意图:

image-20201215230959604

整个过程大致就这四步:

  1. 显示Android启动界面LaunchTheme
  2. 显示普通主题NormalTheme
  3. 普通主题退出到正式进入Flutter界面的过渡效果
  4. 正式进入Flutter界面

如何配置启动页

先看下面这张图,所有配置的东西都在这里面,不用写一行代码。

image-20201215233323859

A:android\app\src\main\AndroidManifest.xml文件中有主要的配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
android:label="闪电侠学习"		# 修改应用的名称,将显示在APP图标下面
android:icon="@mipmap/icon">	# 指定APP图标

android:name=".MainActivity"	# 主要框架页面,你可以在kotlin下面发现MainActivity的定义
android:theme="@style/LaunchTheme"	# 配置主题样式LaunchTheme

<meta-data
	android:name="io.flutter.embedding.android.SplashScreenDrawable"
	android:resource="@drawable/launch_background"	# 第一加载
	/>

<meta-data
	android:name="io.flutter.embedding.android.NormalTheme"
	android:resource="@style/NormalTheme"			# 第二加载
	/>

B:android\app\src\main\res\values\*定义资源文件

这个文件夹下面以XML格式定义了很多资源,资源文件名无所谓,关键是里面的标签。你会发现@style/LaunchTheme这种资源就是在里面定义的。比如style.xml文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>

    <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@android:color/black</item>
    </style>
</resources>

colors.xml文件

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="orange">#FFAB40</color>
    <color name="greens">#44CC11</color>
    <color name="transparent">#00000000</color>
</resources>

C:android\app\src\main\res\drawable\*定义可绘制的资源

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--    <item android:drawable="@android:color/white" />-->
    <item android:drawable="@color/orange" />

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/launch3" />
    </item>
</layer-list>

D:针对不同屏幕大小的图片等文件放在mipmap-*dpi

你会发现下面 这种写法的图片文件都能在mipmap-hdpi中找到,图片后缀无所谓png,jpg都可以成功找到;但最好使用png文件。

1
2
android:icon="@mipmap/icon"
android:src="@mipmap/launch3"

小结:

这些基本上就配置完了,不过实际的使用过程当中我没有看到2和3步的效果,不知道为什么。

改进启动页

一般APP的启动显示过程如下:

image-20201216010408033

前面我们已经用配置的方式解决了"显示logo"的问题,接下来我显示“介绍页”或“推广页”,显示完这些后我们就直接进入APP首页了。直接上代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'login',
      home: SplashScreen(),
      routes: <String, WidgetBuilder>{
        '/IndexPage': (context) => IndexPage()
      },
    );
  }
}

class IndexPage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('首页'),
        centerTitle: true,
      ),
      body: Center(
        child: Text('显示内容',style:Theme.of(context).textTheme.button,),
      ),
    );
  }
}

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Image.network('https://xxx.com/launch/t.png',fit: BoxFit.contain,),
    );
  }
  @override
  void initState() {
    super.initState();
    countDown();
  }
  void countDown(){
    var _duration = Duration(seconds: 10);
    Future.delayed(_duration, _indexPage);
  }
  void _indexPage(){
    Navigator.of(context).pushReplacementNamed('/IndexPage');
  }
}

在模拟器中运行上面的代码,执行过程中能看到三步,效果如下图所示

  1. 显示启动图片
  2. 显示网络加载的图片
  3. 进入首页

image-20201216015206381

小结:

就这样一个简单的APP启动过程就制作好了,有打包图片的开机启动页,有网络拉取图片的广告推广页,最后再进入首页。是不是很简单?但是别看这就实现了,真正想做好还有很多地方需要调整和优化,比如中间过渡可能白屏的问题,要加入更多动画效果,推广页倒计时等。后面继续学习。

(完)