Flutter-自定义闪屏页(SplashScreen)


Splash Screen?

对于Android应用来说,Splash Screen最熟悉不过了.比如为了让启动的时候app不现实白屏,或者为了弄个开屏广告用来盈利,都会用到Splash Screen.

splash

Flutter中如何自定义Splash页面

这里先说一个Android中最基础的:

设置启动主题,并设置一个windowBackground

至于怎么设置主题,太简单了没什么好说的,贴个背景资源代码:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:opacity="opaque">
    <item android:drawable="@android:color/white" />
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_launcher" />
    </item>
</layer-list>

可以看到这里用了一个白色背景和一个图片.

在Flutter中,只设置这个是不够的,为什么?

在MainActivity启动之后,Flutter中的UI数据加载之前这段时间里我们还得设置一个自定义的splash图或者页面,要不然很可能会导致黑屏.

这里也有很多种方法,主要说下经过源码分析之后得到的两种方案:

manifest中通过meta-data设置一个splash资源

            <meta-data
                android:name="io.flutter.embedding.android.SplashScreenDrawable"
                android:resource="@drawable/splash_screen"
                />

这个节点放到MainActivity节点下.

这样就会有在Flutter UI加载完之前显示一个过渡的图片了.

如果只是设置个图片,在实际产品中基本上没什么用,来看看正式一点的做法吧:

自己实现SplashScreen接口

这个接口很简单,就两个方法:

  • createSplashView:创建一个View用于展示Splash页面
  • transitionToFlutter:过渡到Flutter

代码也比较简单,我这里直接用代码手写一个Lotiie的基本布局:

package com.jiangkang.flutter_system

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import io.flutter.embedding.android.SplashScreen
import kotlin.random.Random

/**
 * A Splash Screen based lottie animation
 * it will pause 1s,then enter the main page
 */
class LottieSplashScreen : SplashScreen{

    private val lottieRawIds = arrayOf(
            R.raw.lottie1,
            R.raw.lottie2,
            R.raw.lottie3,
            R.raw.lottie4,
            R.raw.lottie5,
            R.raw.lottie6,
            R.raw.lottie7,
            R.raw.lottie8
    )

    override fun createSplashView(context: Context, savedInstanceState: Bundle?): View? {
        val lottieView = LottieAnimationView(context)
        lottieView.apply {
            repeatMode = LottieDrawable.RESTART
            repeatCount = LottieDrawable.INFINITE
            setAnimation(lottieRawIds[Random(System.currentTimeMillis()).nextInt(0,lottieRawIds.size)])
        }.playAnimation()
        (context as Activity).window.setBackgroundDrawable(ColorDrawable(Color.WHITE))

        val layoutParamsLottie = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT)
                .apply {
                    gravity = Gravity.CENTER
                }
        val rootView = FrameLayout(context)
        rootView.apply {
            layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)
            setBackgroundColor(Color.WHITE)
            addView(lottieView,layoutParamsLottie)
        }
        return rootView
    }

    override fun transitionToFlutter(onTransitionComplete: Runnable) {
        Handler(Looper.getMainLooper()).postDelayed(onTransitionComplete,1000)
    }
}

然后在MainActivity中重写一个方法即可:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.SplashScreen

class MainActivity : FlutterActivity() {

    override fun provideSplashScreen(): SplashScreen? {
        return LottieSplashScreen()
    }

}

Flutter Engine在新版本中使用了新的FlutterActivity,这一点稍微注意一下(我这里用的就是最新的).

源码

https://github.com/jiangkang/flutter-system


文章作者: 姜康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜康 !
评论
 上一篇
FFmpeg简介 FFmpeg简介
模块库 avcodec 用于音视频编解码,支持自带的MPEG4,AAC,MJPEG等编码格式,还支持第三方的编解码,比如H.264(AVC,使用X264编解码器),H.265(HEVC,使用X265编解码器) avdevice 多媒体设备
下一篇 
Android中的ANativeWindow Android中的ANativeWindow
ANativeWindow是什么ANativeWindow是C/C++中定义的一个结构体,等同于Java中的Surface. Android NDK中可以访问到ANativeWindow. ANativeWindow中存放像素信息的结构是:
2020-06-19
  目录