it-swarm.com.de

Hinzufügen eines Begrüßungsbildschirms zu Flutter-Apps

Wie würden Sie nähere Informationen zum Hinzufügen eines Begrüßungsbildschirms zu Flutter-Apps erhalten? Es sollte vor jedem anderen Inhalt geladen und angezeigt werden. Momentan gibt es einen kurzen Farbblitz, bevor das Widget Scaffold (home: X) geladen wird.

39
Pieter

Ich möchte etwas mehr Licht in die eigentliche Art bringen, Splash-Bildschirm in Flutter zu machen.

Ich folgte ein wenig der Spur hier und sah, dass die Dinge beim Splash Screen in Flutter nicht so schlecht aussehen.

Vielleicht denken die meisten Devs (wie ich), dass in Flutter standardmäßig kein Splash-Bildschirm vorhanden ist, und sie müssen etwas dagegen unternehmen. Eigentlich gibt es einen Splash-Bildschirm, aber er ist mit weißem Hintergrund und niemand kann verstehen, dass es bereits einen Splash-Screen für iOS und Android gibt. 

Das ist wirklich cool, denn das einzige, was der Entwickler tun muss, ist, das Branding-Image an die richtige Stelle zu setzen, und der Begrüßungsbildschirm beginnt genau so zu funktionieren.

Nun, so geht es Schritt für Schritt:

Zuerst für Android (weil meine Lieblingsplattform :))

  1. Suchen Sie den Ordner "Android" in Ihrem Flutter-Projekt. 

  2. Navigieren Sie zum Ordner app -> src -> main -> res und legen Sie alle Varianten Ihres Branding-Images in den entsprechenden Ordnern ab. Zum Beispiel:

    • das Bild mit der Dichte 1 muss in Mipmap-mdpi platziert werden. 
    • das Bild mit der Dichte 1.5 muss in Mipmap-HDpi platziert werden. 
    • das Bild mit der Dichte 2 muss in Mipmap-xdpi platziert werden. 
    • das Bild mit der Dichte 3 muss in Mipmap-xxdpi platziert werden.
    • das Bild mit der Dichte 4 muss in Mipmap-xxxdpi platziert werden. 

Standardmäßig gibt es für den Android-Ordner kein drawable-mdpi, drawable-hdpi usw., aber jeder kann erstellen, wenn er möchte. Deshalb müssen die Bilder in Mipmap-Ordnern abgelegt werden. Außerdem wird der Standard-XML-Code für den Begrüßungsbildschirm (in Android) in @mipmap nicht in @drawable angezeigt (Sie können ihn ändern, wenn Sie möchten).

  1. Der letzte Schritt in Android besteht darin, einigen Code in drawable/launch_background.xml zu kommentieren. Navigieren Sie zu App -> src -> main -> res-> drawable und öffnen Sie die Datei launch_background.xml. In dieser Datei sehen Sie, warum der Hintergrund des Slash-Bildschirms weiß ist. Um das Branding-Image, das wir in Schritt 2 platziert haben, anzuwenden, müssen wir einige der XML-Codes in Ihrer Datei launch_background.xml auskommentieren. Nach der Änderung sollte der Code folgendermaßen aussehen:

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

Bitte beachten Sie, dass wir den weißen Hintergrundcode kommentieren und den Code zum Mipmap-Bild kommentieren. Wenn jemand interessiert ist, wird diese launch_background.xml in der Datei styles.xml verwendet.

Jetzt für iOS:

  1. Suchen Sie den "ios" -Ordner in Ihrem Flutter-Projekt. 

  2. Navigieren Sie zu Runner -> Assets.xcassets -> LaunchImage.imageset. Es sollte LaunchImage.png, [email protected] usw. geben. Jetzt müssen Sie diese Bilder durch Ihre Branding-Image-Varianten ersetzen. Zum Beispiel:

Wenn ich mich nicht irre, existiert [email protected] nicht standardmäßig, aber Sie können leicht eines erstellen. Wenn [email protected] nicht vorhanden ist, müssen Sie es auch in der Datei Contents.json angeben, die sich in demselben Verzeichnis wie die Bilder befindet. Nach der Änderung sieht meine Contents.json-Datei folgendermaßen aus:

{
  "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"
  }
}

Und das sollte alles sein. Wenn Sie beim nächsten Mal Ihre App ausführen, sollte auf Android und iOS der richtige Splash-Bildschirm mit dem von Ihnen hinzugefügten Branding-Image angezeigt werden.

Vielen Dank

101
Sniper

Es gibt noch kein gutes Beispiel dafür, aber Sie können es selbst mit den nativen Tools für jede Plattform tun:

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

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

Abonnieren Sie issue 8147 für Updates zu Beispielcode für Begrüßungsbildschirme. Wenn das schwarze Flimmern zwischen dem Begrüßungsbildschirm und der App unter iOS Sie stört, abonnieren Sie issue 8127 für Updates.

Bearbeiten: Ab dem 31. August 2017 ist in der neuen Projektvorlage eine verbesserte Unterstützung für Startbildschirme verfügbar. Siehe # 11505 .

11
Collin Jackson

Wenn Sie Ihr Projekt flutter created haben, können Sie den Schritten unter https://flutter.io/assets-and-images/#updating-the-launch-screen folgen. 

9
xster

Sie sollten unter Code versuchen, für mich gearbeitet

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

Gehen Sie für Android zu Android> App> src> main> res> drawable> launcher_background.xml

Kommentieren Sie dies jetzt und ersetzen Sie @ mipmap/launch_image durch Ihren Bildspeicherort.

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

Sie können die Farbe Ihres Bildschirms hier ändern - 

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

Sowohl @Collin Jackson als auch @Sniper haben recht. Führen Sie die folgenden Schritte aus, um Startbilder in Android bzw. iOS einzurichten. Dann können Sie in MyApp (), in Ihrem initState (), Future.delayed verwenden, um einen Timer einzurichten oder eine beliebige API aufzurufen. Bis die Antwort von der Zukunft zurückgegeben wird, werden Ihre Startsymbole angezeigt. Wenn die Antwort kommt, können Sie nach dem Begrüßungsbildschirm zu dem Bildschirm wechseln, zu dem Sie wechseln möchten. Sie können diesen Link sehen: Flatter Splash Screen

4
Vikas Pandey

personen, die nach Anwendung der verifizierten Antwort ein fehlerhaftes Bild erhalten, das nicht gefunden wurde, stellen sicher, dass Sie @ mipmap/ic_launcher anstelle von @ mipmap/ic_launcher.png hinzufügen.

4
Md Sadab Wasim

Das Hinzufügen einer Seite wie unten und des Routings kann hilfreich sein

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),
                    )
                  ],
                ),
              )
            ],
          )
        ],
      ),
    );
  }
}

Wenn Sie mitmachen möchten, lesen Sie: https://www.youtube.com/watch?v=FNBuo-7zg2Q

3
goops17

Der Code von Jaldhi Bhatt funktioniert nicht für mich.

Flutter wirft einen ' Navigator-Vorgang ab, der mit einem Kontext angefordert wurde, der keinen Navigator enthält.'

Ich habe den Code korrigiert, der die Navigator-Konsumerkomponente in eine andere Komponente einhüllt, die den Navigatorkontext mithilfe von Routen initialisiert, wie in this article erwähnt.

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,
        )
    );
  }
}
2
GiBi

Flutter bietet tatsächlich eine einfachere Möglichkeit, Splash Screen zu unserer Anwendung hinzuzufügen. Wir müssen zuerst eine einfache Seite entwerfen, während wir andere App-Bildschirme entwerfen. Sie müssen es zu einem StatefulWidget machen, da sich der Status in wenigen Sekunden ändert.

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'),
      ),
    );
  }
}

Logik Rufen Sie im initState () einen Timer () mit der gewünschten Dauer von 3 Sekunden auf. Schieben Sie den Navigator auf Startbildschirm unserer Anwendung.

Hinweis: Die Anwendung sollte nur einen Begrüßungsbildschirm anzeigen, der Benutzer sollte beim Drücken der Zurück-Taste nicht wieder dorthin zurückkehren. Dazu verwenden wirNavigator.pushReplacement (). Es wird zu einem neuen Bildschirm verschoben und der vorherige Bildschirm aus dem Navigationsverlaufsstapel entfernt.

Zum besseren Verständnis besuchen Sie Flutter: Entwerfen Sie Ihren eigenen Begrüßungsbildschirm

1
kowsalya_ckar

Für den Fall, dass Sie einen zweiten Begrüßungsbildschirm (nach dem nativen) wünschen, ist hier ein einfaches Beispiel, das funktioniert:

class SplashPage extends StatelessWidget {
  SplashPage(BuildContext context) {
    Future.delayed(const Duration(seconds: 3), () {
      // Navigate here to next screen
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text('Splash screen here');
  }
}
1
david72

Es gibt mehrere Möglichkeiten, dies zu tun, aber die einfachste, die ich verwende, ist:

Für Startsymbole verwende ich die Flatterbibliothek Flutter Launcher Icon

Für den benutzerdefinierten Begrüßungsbildschirm erstelle ich unterschiedliche Bildschirmauflösungen und füge die Begrüßungsbilder gemäß der Auflösung für Android dem Ordner mipmap hinzu.

Der letzte Teil ist das Anpassen der Datei launch_background.xml im drawable-Ordner im res-Ordner in Android.

Ändern Sie einfach Ihren Code wie folgt:

<?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>

Wenige Entwickler, die ich gesehen habe, fügen den Splash als drawable hinzu. Ich habe dies versucht, aber irgendwie schlägt der Build in Flutter 1.0.0 und Dart SDK 2.0+ fehl. Deshalb ziehe ich es vor, den Splash im Bitmap-Bereich hinzuzufügen.

die Erstellung von iOS-Begrüßungsbildschirmen ist etwas einfacher.

Aktualisieren Sie im Ordner "Runner" unter iOS die Dateien "LaunchImage.png" mit Ihren benutzerdefinierten Bildern des Begrüßungsbildschirms mit denselben Namen wie "LaunchImage.png @ 2x", @ 3x, @ 4x.

Nur ein Zusatz finde ich gut, ein 4x-Bild auch im LaunchImage.imageset zu haben. Aktualisieren Sie einfach Ihren Code in Content.json mit den folgenden Zeilen unterhalb der 3-fach Skalierung, um eine 4-fach Skalierungsoption hinzuzufügen:

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