web-dev-qa-db-ja.com

Flutterアプリにスプラッシュスクリーンを追加する

Flutterアプリにスプラッシュスクリーンを追加するにはどのようにアプローチしますか?他のコンテンツの前にロードして表示する必要があります。現在、Scaffold(home:X)ウィジェットがロードされる前に短い色のフラッシュがあります。

61
Pieter

Flutterのスプラッシュスクリーンを実際に行う方法にもう少し光を当てたいと思います。

私はトレースを少したどった here で、Flutterのスプラッシュスクリーンについてそれほど悪くないことがわかりました。

たぶんほとんどの開発者(私のような)は、Flutterにはデフォルトでスプラッシュスクリーンがないと考えており、それについて何かをする必要があります。実際にはスプラッシュスクリーンがありますが、背景が白いため、iOSおよびデフォルトでAndroidのスプラッシュスクリーンが既に存在することを誰も理解できません。

開発者が行う必要があるのは、ブランディングイメージを適切な場所に配置することだけであり、スプラッシュスクリーンはそのように機能し始めるので、これは実際にクールです。

次に、これをどのように行うかをステップごとに示します。

まずAndroid用(私のお気に入りのプラットフォームだからです:))

  1. Flutterプロジェクトで「Android」フォルダーを見つけます。

  2. アプリ-> src->メイン-> resフォルダーを参照し、ブランドイメージのすべてのバリエーションを対応するフォルダーに配置します。例えば:

    • 密度1の画像をmipmap-mdpiに配置する必要があります。
    • 密度1.5の画像をmipmap-hdpiに配置する必要があります。
    • 密度2の画像をmipmap-xdpiに配置する必要があります。
    • 密度3の画像をmipmap-xxdpiに配置する必要があります。
    • 密度4の画像をmipmap-xxxdpiに配置する必要があります。

Androidフォルダーのデフォルトでは、drawable-mdpi、drawable-hdpiなどはありませんが、必要に応じて誰でも作成できます。そのため、画像をミップマップフォルダーに配置する必要があります。さらに、(Androidの)スプラッシュ画面に関するデフォルトのXMLコードは、@ drawableではなく@mipmapに表示されます(必要に応じて変更できます)。

  1. Androidの最後のステップは、drawable/launch_background.xmlの一部のコードのコメントを解除することです。 app-> src-> main-> res-> drawableを参照し、launch_background.xmlを開きます。このファイル内では、スラッシュ画面の背景が白である理由がわかります。ステップ2で配置したブランディングイメージを適用するには、launch_background.xmlファイル内のXMLコードのコメントを外す必要があります。そのため、変更後のコードは次のようになります。

    <!--<item Android:drawable="@Android:color/white" />-->
    
    <item>
    
        <bitmap
            Android:gravity="center"
            Android:src="@mipmap/your_image_name" />
    
    </item>
    

白い背景コードにコメントを付け、ミップマップ画像に関するコードのコメントを外すことに注意してください。誰かが興味を持っている場合、このlaunch_background.xmlはstyles.xmlファイルで使用されます。

iOSの場合:

  1. Flutterプロジェクトで「ios」フォルダーを見つけます。

  2. Runner-> Assets.xcassets-> LaunchImage.imagesetを参照します。 LaunchImage.png、LaunchImage @ 2x.pngなどがあるはずです。ここで、これらの画像をブランディング画像バリアントに置き換える必要があります。例えば:

    • 密度1の画像は、LaunchImage.pngをオーバーライドする必要があります。
    • 密度2の画像は[email protected]をオーバーライドする必要があります。
    • 密度3の画像は[email protected]をオーバーライドする必要があります。
    • 密度4の画像は[email protected]をオーバーライドする必要があります。

間違っていない場合、LaunchImage @ 4x.pngはデフォルトでは存在しませんが、簡単に作成できます。 [email protected]が存在しない場合は、Contents.jsonファイルでも宣言する必要があります。Contents.jsonファイルは画像と同じディレクトリにあります。変更後、Contents.jsonファイルは次のようになります。

{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "LaunchImage.png",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "filename" : "[email protected]",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "filename" : "[email protected]",
      "scale" : "3x"
    },
    {
      "idiom" : "universal",
      "filename" : "[email protected]",
      "scale" : "4x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

そして、これですべてです。次回アプリを実行するとき、AndroidおよびiOSで、追加したブランドイメージを含む適切なスプラッシュスクリーンが表示されます。

ありがとう

121
Sniper

プロジェクトをflutter createdする場合、 https://flutter.io/assets-and-images/#updating-the-launch-screen の手順に従うことができます。

18
xster

この良い例はまだありませんが、各プラットフォームのネイティブツールを使用して自分で行うことができます。

iOS: https://docs.nativescript.org/publishing/creating-launch-screens-ios

Android: https://www.bignerdranch.com/blog/splash-screens-the-right-way/

スプラッシュ画面のサンプルコードの更新については、 issue 8147 を購読してください。スプラッシュ画面とiOSのアプリとの間の黒いちらつきが気になる場合は、 issue 8127 を購読して更新してください。

編集:2017年8月31日の時点で、新しいプロジェクトテンプレートでスプラッシュスクリーンのサポートが改善されました。 #11505を参照

12
Collin Jackson

Androidの場合、Android> app> src> main> res> drawable> launcher_background.xmlに移動します

ここでコメントを外し、@ mipmap/launch_imageを画像の場所に置き換えます。

<item>
      <bitmap
          Android:gravity="center"
          Android:src="@mipmap/launch_image" />
</item>

ここで画面の色を変更できます-

<item Android:drawable="@Android:color/white" />
6

以下のコードを試してみてください、私のために働いた

import 'Dart:async';
import 'package:attendance/components/appbar.Dart';
import 'package:attendance/homepage.Dart';
import 'package:flutter/material.Dart';

class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {


void handleTimeout() {
  Navigator.of(context).pushReplacement(new MaterialPageRoute(
    builder: (BuildContext context) => new MyHomePage()));
}

startTimeout() async {
  var duration = const Duration(seconds: 3);
  return new Timer(duration, handleTimeout);
}

@override
void initState() {
  // TODO: implement initState
  super.initState();

  _iconAnimationController = new AnimationController(
      vsync: this, duration: new Duration(milliseconds: 2000));

  _iconAnimation = new CurvedAnimation(
      parent: _iconAnimationController, curve: Curves.easeIn);
  _iconAnimation.addListener(() => this.setState(() {}));

  _iconAnimationController.forward();

  startTimeout();
}

@override
Widget build(BuildContext context) {
  return new Scaffold(
    body: new Scaffold(
      body: new Center(
        child: new Image(
        image: new AssetImage("images/logo.png"),
        width: _iconAnimation.value * 100,
        height: _iconAnimation.value * 100,
      )),
    ),
  );
}
}
6
Jaldhi Bhatt

@Collin Jacksonと@Sniperはどちらも正しい。これらの手順に従って、AndroidおよびiOSでそれぞれ起動画像を設定できます。次に、MyApp()、initState()で、Future.delayedを使用してタイマーを設定したり、任意のAPIを呼び出したりできます。 Futureから応答が返されるまで、起動アイコンが表示され、応答が来たら、スプラッシュスクリーンの後に移動したい画面に移動できます。このリンクを見ることができます: Flutter Splash Screen

4
Vikas

検証済みの回答を適用した後に画像が見つからないなどのエラーが表示される場合は、@ mipmap/ic_launcher.pngの代わりに@ mipmap/ic_launcherを追加していることを確認してください

4
Md Sadab Wasim

以下のようなページとルーティングを追加すると役立つ場合があります

import 'Dart:async';

import 'package:flutter/material.Dart';
import 'package:flutkart/utils/flutkart.Dart';
import 'package:flutkart/utils/my_navigator.Dart';

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Timer(Duration(seconds: 5), () => MyNavigator.goToIntro(context));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          Container(
            decoration: BoxDecoration(color: Colors.redAccent),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Expanded(
                flex: 2,
                child: Container(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      CircleAvatar(
                        backgroundColor: Colors.white,
                        radius: 50.0,
                        child: Icon(
                          Icons.shopping_cart,
                          color: Colors.greenAccent,
                          size: 50.0,
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(top: 10.0),
                      ),
                      Text(
                        Flutkart.name,
                        style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: 24.0),
                      )
                    ],
                  ),
                ),
              ),
              Expanded(
                flex: 1,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    CircularProgressIndicator(),
                    Padding(
                      padding: EdgeInsets.only(top: 20.0),
                    ),
                    Text(
                      Flutkart.store,
                      softWrap: true,
                      textAlign: TextAlign.center,
                      style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 18.0,
                          color: Colors.white),
                    )
                  ],
                ),
              )
            ],
          )
        ],
      ),
    );
  }
}

フォローしたい場合は、以下を参照してください: https://www.youtube.com/watch?v=FNBuo-7zg2Q

2
goops17

Flutterを使用すると、アプリケーションにスプラッシュスクリーンを簡単に追加できます。他のアプリ画面を設計するとき、最初に基本的なページを設計する必要があります。この状態は数秒で変わるため、StatefulWidgetにする必要があります。

import 'Dart:async';
import 'package:flutter/material.Dart';
import 'home.Dart';

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    Timer(
        Duration(seconds: 3),
        () => Navigator.of(context).pushReplacement(MaterialPageRoute(
            builder: (BuildContext context) => HomeScreen())));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Image.asset('assets/splash.png'),
      ),
    );
  }
}

LogicinitState()内で、Timer()必要に応じて期間を指定して、3秒にしました。一度完了したら、ナビゲーターをアプリケーションのホーム画面にプッシュします。

注:アプリケーションはスプラッシュ画面を1つだけ表示する必要があり、ユーザーは戻るボタンを押しても再び画面に戻るべきではありません。このために、Navigator.pushReplacement()を使用します。新しい画面に移動して削除しますナビゲーション履歴スタックの前の画面。

よりよく理解するには、 フラッター:独自のスプラッシュスクリーンを設計してください にアクセスしてください。

1
kowsalya_ckar

Jaldhi Bhattのコードはうまくいきません。

Flutterは「 ナビゲーターを含まないコンテキストで要求されたナビゲーター操作 」をスローします。

this の記事に記載されているように、ルートを使用してNavigatorコンテキストを初期化する別のコンポーネント内のNavigatorコンシューマコンポーネントをラップするコードを修正しました。

import 'Dart:async';

import 'package:flutter/material.Dart';
import 'package:my-app/view/main-view.Dart';

class SplashView extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        home: Builder(
          builder: (context) => new _SplashContent(),
        ),
        routes: <String, WidgetBuilder>{
          '/main': (BuildContext context) => new MainView()}
    );
  }
}

class _SplashContent extends StatefulWidget{

  @override
  _SplashContentState createState() => new _SplashContentState();
}

class _SplashContentState extends State<_SplashContent>
    with SingleTickerProviderStateMixin {

  var _iconAnimationController;
  var _iconAnimation;

  startTimeout() async {
    var duration = const Duration(seconds: 3);
    return new Timer(duration, handleTimeout);
  }

  void handleTimeout() {
    Navigator.pushReplacementNamed(context, "/main");
  }

  @override
  void initState() {
    super.initState();

    _iconAnimationController = new AnimationController(
        vsync: this, duration: new Duration(milliseconds: 2000));

    _iconAnimation = new CurvedAnimation(
        parent: _iconAnimationController, curve: Curves.easeIn);
    _iconAnimation.addListener(() => this.setState(() {}));

    _iconAnimationController.forward();

    startTimeout();
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
        child: new Image(
          image: new AssetImage("images/logo.png"),
          width: _iconAnimation.value * 100,
          height: _iconAnimation.value * 100,
        )
    );
  }
}
1
GiBi

これを行うには複数の方法がありますが、私が使用する最も簡単な方法は次のとおりです。

起動アイコンには、フラッターライブラリを使用します Flutter Launcher Icon

カスタムスプラッシュスクリーンの場合Androidの解像度に従って、さまざまな画面解像度を作成し、mipmapフォルダーにスプラッシュ画像を追加します。

最後の部分は、Androidのresフォルダーにあるdrawableフォルダーのlaunch_background.xmlを調整することです。

コードを次のように変更するだけです。

<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <!-- <item Android:drawable="@Android:color/white" />
    <item Android:drawable="@drawable/<splashfilename>" />     --> -->

    <!-- You can insert your own image assets here -->
    <item>
        <bitmap
            Android:gravity="center"
            Android:src="@mipmap/<Your splash image name here as per the mipmap folder>"/>
    </item>
</layer-list>

スプラッシュを描画可能として追加した開発者はほとんどいませんでしたが、これを試してみましたが、Flutter 1.0.0およびDart SDK 2.0+でビルドが失敗します。したがって、ビットマップセクションにスプラッシュを追加することを好みます。

iOSのスプラッシュスクリーンの作成はかなり簡単です。

IOSのRunnerフォルダーで、LaunchImage.pngファイルを、LaunchImage.png @ 2x、@ 3x、@ 4xと同じ名前のカスタムスプラッシュスクリーン画像で更新します。

さらに、LaunchImage.imagesetにも4倍の画像を含めると良いと思います。 Content.jsonのコードを3xスケール以下の行で更新して、4xスケールオプションを追加するだけです。

{
      "idiom" : "universal",
      "filename" : "[email protected]",
      "scale" : "4x"
    }
1
Prashant Gupta