Come approcceresti l'aggiunta di una schermata iniziale alle app Flutter? Dovrebbe essere caricato e visualizzato prima di qualsiasi altro contenuto. Attualmente c'è un breve lampo di colore prima che il widget Scaffold (home: X) venga caricato.
Come approcceresti l'aggiunta di una schermata iniziale alle app Flutter? Dovrebbe essere caricato e visualizzato prima di qualsiasi altro contenuto. Attualmente c'è un breve lampo di colore prima che il widget Scaffold (home: X) venga caricato.
Risposte:
Voglio portare un po 'più di luce sul modo reale di fare uno schermo Splash in Flutter.
Ho seguito un po 'la traccia qui e ho visto che le cose non stanno andando così male sullo Splash Screen in Flutter.
Forse la maggior parte degli sviluppatori (come me) pensa che non ci sia Schermata iniziale per impostazione predefinita in Flutter e devono fare qualcosa al riguardo. C'è una schermata iniziale, ma è con sfondo bianco e nessuno può capire che esiste già una schermata iniziale per iOS e Android.
L'unica cosa che lo sviluppatore deve fare è mettere l'immagine del marchio nel posto giusto e la schermata iniziale inizierà a funzionare proprio così.
Ecco come puoi farlo passo dopo passo:
Prima su Android (perché è la mia piattaforma preferita :))
Trova la cartella "android" nel tuo progetto Flutter.
Passare all'app -> src -> main -> res cartella e posizionare tutte le varianti dell'immagine di branding nelle cartelle corrispondenti. Per esempio:
Di default nella cartella Android non ci sono drawable-mdpi, drawable-hdpi, ecc., Ma possiamo crearli se vogliamo. Per questo motivo le immagini devono essere inserite nelle cartelle mipmap. Anche il codice XML predefinito sulla schermata di Splash (in Android) utilizzerà @mipmap, anziché la risorsa @drawable (puoi cambiarlo se vuoi).
L'ultimo passaggio su Android è decommentare parte del codice XML nel file drawable / launch_background.xml. Passare all'app -> src -> main -> res-> drawable e aprire launch_background.xml. All'interno di questo file, vedrai perché lo sfondo della barra è bianco. Per applicare l'immagine di branding che abbiamo inserito nel passaggio 2, dobbiamo decommentare parte del codice XML nel tuo file launch_background.xml. Dopo la modifica, il codice dovrebbe apparire come:
<!--<item android:drawable="@android:color/white" />-->
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/your_image_name" />
</item>
Prestare attenzione a commentare il codice XML per lo sfondo bianco e rimuovere il commento dal codice sull'immagine mipmap. Se qualcuno è interessato, il file launch_background.xml viene utilizzato nel file styles.xml.
Secondo su iOS:
Trova la cartella "ios" nel tuo progetto Flutter.
Passare a Runner -> Assets.xcassets -> LaunchImage.imageset. Dovrebbero esserci LaunchImage.png, LaunchImage@2x.png, ecc. Ora devi sostituire queste immagini con le varianti di immagine del tuo marchio. Per esempio:
Se non sbaglio LaunchImage@4x.png non esiste per impostazione predefinita, ma puoi crearne uno facilmente. Se LaunchImage@4x.png non esiste, devi dichiararlo anche nel file Contents.json, che si trova nella stessa directory come le immagini. Dopo la modifica, il mio file Contents.json è simile al seguente:
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@4x.png",
"scale" : "4x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Questo dovrebbe essere tutto ciò di cui hai bisogno, la prossima volta che avvii la tua app, su Android o iOS dovresti avere la giusta schermata iniziale con l'immagine del marchio che hai aggiunto.
Grazie
Cannot resolve symbol '@mipmap/ic_launcher'
in Android Studio 3.1.1 (anche dopo la ricostruzione della cache), tuttavia, l'app è stata compilata ed eseguita senza errori e viene visualizzato il grafico di avvio.
Se flutter create
progetti il tuo progetto, puoi seguire i passaggi su https://flutter.io/assets-and-images/#updating-the-launch-screen .
Flutter offre in realtà un modo più semplice per aggiungere Splash Screen alla nostra applicazione. Per prima cosa dobbiamo progettare una pagina di base mentre progettiamo altre schermate delle app. Devi renderlo un StatefulWidget poiché lo stato di questo cambierà in pochi secondi.
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'),
),
);
}
}
Logica All'interno di initState () , chiama un Timer () con la durata, come desideri, l'ho fatto 3 secondi, una volta fatto spingi il navigatore nella schermata principale della nostra applicazione.
Nota: l'applicazione deve mostrare la schermata iniziale solo una volta, l'utente non deve tornare nuovamente alla pressione del pulsante Indietro. Per questo, usiamo Navigator.pushReplacement () , passerà a una nuova schermata e rimuoverà la schermata precedente dallo stack della cronologia di navigazione.
Per una migliore comprensione, visitare Flutter: Progetta la tua schermata iniziale
Non c'è ancora un buon esempio di questo, ma puoi farlo tu stesso usando gli strumenti nativi per ogni piattaforma:
iOS: https://docs.nativescript.org/publishing/creating-launch-screens-ios
Android: https://www.bignerdranch.com/blog/splash-screens-the-right-way/
Abbonati al numero 8147 per aggiornamenti sul codice di esempio per schermate iniziali. Se lo sfarfallio nero tra la schermata iniziale e l'app su iOS ti dà fastidio, iscriviti al numero 8127 per gli aggiornamenti.
Modifica: dal 31 agosto 2017, il supporto migliorato per le schermate iniziali è ora disponibile nel nuovo modello di progetto. Vedi # 11505 .
Per Android, vai su android> app> src> main> res> drawable> launcher_background.xml
Ora decommenta questo e sostituisci @ mipmap / launch_image , con la tua posizione dell'immagine.
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item>
Puoi cambiare il colore del tuo schermo qui -
<item android:drawable="@android:color/white" />
Il modo più semplice per aggiungere una schermata iniziale in flutter è imho questo pacchetto: https://pub.dev/packages/flutter_native_splash
Aggiungi le tue impostazioni al file pubspec.yaml del tuo progetto o crea un file nella cartella del tuo progetto root chiamato flutter_native_splash.yaml con le tue impostazioni.
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
l'immagine deve essere un file png.
Puoi usare anche # a colori. color: "# 42a5f5" Puoi anche impostare android o ios su false se non vuoi creare una schermata iniziale per una piattaforma specifica.
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
android: false
Nel caso in cui l'immagine debba utilizzare tutte le schermate disponibili (larghezza e altezza) è possibile utilizzare la proprietà di riempimento.
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
fill: true
Nota: la proprietà fill non è ancora implementata per le schermate iniziali iOS.
Se si desidera disabilitare la schermata iniziale a schermo intero su Android, è possibile utilizzare la proprietà android_disable_fullscreen.
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
android_disable_fullscreen: true
Dopo aver aggiunto le impostazioni, eseguire il pacchetto con
flutter pub pub run flutter_native_splash:create
Al termine dell'esecuzione del pacchetto, la schermata iniziale è pronta.
Dovresti provare sotto il codice, ha funzionato per me
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,
)),
),
);
}
}
le persone che ottengono l'errore come l'immagine non trovata dopo aver applicato la risposta verificata si assicurano di aggiungere @ mipmap / ic_launcher anziché @ mipmap / ic_launcher.png
Sia @Collin Jackson che @Sniper hanno ragione. Puoi seguire questi passaggi per configurare le immagini di avvio rispettivamente in Android e iOS. Quindi in MyApp (), in initState (), è possibile utilizzare Future.delayed per impostare un timer o chiamare qualsiasi API. Fino a quando la risposta non verrà restituita dal futuro, verranno visualizzate le icone di avvio e, man mano che la risposta arriva, puoi passare alla schermata in cui vuoi andare dopo la schermata iniziale. Puoi vedere questo link: Schermata Flutter Splash
L'aggiunta di una pagina come di seguito e il routing potrebbero essere utili
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),
)
],
),
)
],
)
],
),
);
}
}
Se vuoi seguire, vedi: https://www.youtube.com/watch?v=FNBuo-7zg2Q
Molteplici modi in cui potresti farlo, ma il più semplice che utilizzo è:
Per le icone di lancio uso la libreria Flutter Icona di avvio di flutter
Per la schermata iniziale personalizzata creo diverse risoluzioni dello schermo e quindi aggiungo le immagini iniziali nella cartella mipmap secondo la risoluzione per Android.
L'ultima parte sta modificando launch_background.xml nella cartella drawable nella cartella res in Android.
Basta cambiare il codice per apparire come di seguito:
<?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>
Pochi sviluppatori che ho visto aggiungono lo splash come disegnabile, l'ho provato ma in qualche modo la build fallisce in Flutter 1.0.0 e Dart SDK 2.0+. Pertanto preferisco aggiungere lo splash nella sezione bitmap.
La creazione di iOS Splash-screen è piuttosto semplice.
Nella cartella Runner in iOS basta aggiornare i file LaunchImage.png con le immagini dello schermo Splash personalizzate con gli stessi nomi di LaunchImage.png @ 2x, @ 3x, @ 4x.
Solo un'aggiunta mi fa piacere avere anche un'immagine 4x nel LaunchImage.imageset. Basta aggiornare il codice in Content.json con le seguenti righe, sotto la scala 3x per aggiungere un'opzione di scala 4x:
{
"idiom" : "universal",
"filename" : "LaunchImage@4x.png",
"scale" : "4x"
}
rendi la tua app materiale così
=> Aggiungi dipendenza
=> import import 'pacchetto: splashscreen / splashscreen.dart';
import 'package:flutter/material.dart';
import 'package:splashscreen/splashscreen.dart';
import 'package:tic_tac_toe/HomePage.dart';
void main(){
runApp(
MaterialApp(
darkTheme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: new MyApp(),
)
);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new SplashScreen(
seconds: 6,
navigateAfterSeconds: new HomePage(),
title: new Text('Welcome',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 26.0,
color: Colors.purple,
),
),
image: Image.asset("images/pic9.png"),
backgroundColor: Colors.white,
photoSize: 150.0,
);
}
}
L'output finale dello schermo come questo è possibile cambiare secondo in base alle proprie esigenze il cerchio sarà circolare circolare
Questo è il modo migliore e privo di errori per aggiungere la schermata iniziale dinamica in Flutter.
MAIN.DART
import 'package:flutter/material.dart';
import 'constant.dart';
void main() => runApp(MaterialApp(
title: 'GridView Demo',
home: SplashScreen(),
theme: ThemeData(
primarySwatch: Colors.red,
accentColor: Color(0xFF761322),
),
routes: <String, WidgetBuilder>{
SPLASH_SCREEN: (BuildContext context) => SplashScreen(),
HOME_SCREEN: (BuildContext context) => BasicTable(),
//GRID_ITEM_DETAILS_SCREEN: (BuildContext context) => GridItemDetails(),
},
));
SPLASHSCREEN.DART
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:app_example/constants.dart';
class SplashScreen extends StatefulWidget {
@override
SplashScreenState createState() => new SplashScreenState();
}
class SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
var _visible = true;
AnimationController animationController;
Animation<double> animation;
startTime() async {
var _duration = new Duration(seconds: 3);
return new Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.of(context).pushReplacementNamed(HOME_SCREEN);
}
@override
dispose() {
animationController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 2),
);
animation =
new CurvedAnimation(parent: animationController, curve: Curves.easeOut);
animation.addListener(() => this.setState(() {}));
animationController.forward();
setState(() {
_visible = !_visible;
});
startTime();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
new Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 30.0),
child: new Image.asset(
'assets/images/powered_by.png',
height: 25.0,
fit: BoxFit.scaleDown,
),
)
],
),
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Image.asset(
'assets/images/logo.png',
width: animation.value * 250,
height: animation.value * 250,
),
],
),
],
),
);
}
}
CONSTANTS.DART
String SPLASH_SCREEN='SPLASH_SCREEN';
String HOME_SCREEN='HOME_SCREEN';
HOMESCREEN.DART
import 'package:flutter/material.dart';
class BasicTable extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Table Widget")),
body: Center(child: Text("Table Widget")),
);
}
}
Il codice di Jaldhi Bhatt non funziona per me.
Flutter genera un'operazione ' Navigator richiesta con un contesto che non include Navigator ".
Ho corretto il codice che racchiude il componente consumer Navigator all'interno di un altro componente che inizializza il contesto Navigator usando le rotte, come menzionato in questo articolo.
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,
)
);
}
}
Nel caso in cui desideri una schermata iniziale secondaria (dopo quella nativa), ecco un semplice esempio che funziona:
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');
}
}
Flutter ti offre la possibilità di avere una schermata iniziale per impostazione predefinita, ma ci sono molti plugin che possono fare il lavoro. Se non si desidera utilizzare un plug-in per l'attività e si teme che l'aggiunta di un nuovo plug-in possa influire sulla dimensione dell'app. Quindi puoi farlo in questo modo.
Per Android
Apri launch_background.xml quindi puoi inserire l'immagine della schermata iniziale o il colore sfumato che desideri. Questa è la prima cosa che vede l'utente quando apre l'app.
Per IOS
Apri la tua app usando Xcode, fai clic su Runner> Assest.xcassets> LaunchImage, puoi aggiungere l'immagine qui. Se si desidera modificare la posizione che l'immagine della schermata di avvio dovrebbe assumere o assomigliare, è possibile modificarla su LaunchScreen.storyboard.
Ecco i passaggi per la configurazione della schermata iniziale in entrambe le piattaforme IOS e Android per la tua app Flutter.
Piattaforma IOS
Tutte le app inviate all'Apple App Store devono utilizzare uno storyboard Xcode per fornire la schermata di avvio dell'app. Facciamo questo in 3 passaggi: -
Passaggio 1 : Apri ios / Runner.xcworkspace dalla radice della directory dell'app.
Passaggio 2 : selezionare Runner / Assets.xcassets da Project Navigator e trascinare le immagini di avvio di tutte le dimensioni (2x, 3x, ecc.). Puoi anche generare diverse dimensioni di immagini da https://appicon.co/#image-sets
Passo 3 : Puoi vedere il file LaunchScreen.storyboard che mostra l'immagine fornita, qui puoi anche cambiare la posizione dell'immagine semplicemente trascinandola. Per ulteriori informazioni, consultare la documentazione ufficiale https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/launch-screen/
Piattaforma Android
In Android, viene visualizzata una schermata di avvio durante l'inizializzazione dell'app Android. Impostiamo questa schermata di avvio in 3 passaggi: -
Passaggio 1 : Apri il file android / app / src / main / res / drawable / launch_background.xml.
Passaggio 2 : al numero riga 4 è possibile selezionare il colore desiderato: -
<item android:drawable="@android:color/white" />
Passaggio 3 : Alla riga numero 10 è possibile modificare l'immagine: -
android:src="@mipmap/launch_image"
Questo è tutto, il gioco è fatto! Happy Coding :)
Per l'
app Android -> src -> main -> res -> drawble-> launch_background.xml e decommenta il blocco commentato in questo modo
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" /></item>
c'è qualcuno che affronta qualche errore dopo aver codificato come questo
Usa la sincronizzazione con il sistema in Android Studio o la cache non valida e ripristinata.Questo ha risolto il mio problema Nella modalità di debug flutter impiega un po 'di tempo per la schermata iniziale. Dopo la compilazione si ridurrà come Android nativo
Flutter.dev fornisce già la migliore risposta, che non è un bug né un problema, solo config. Basta leggere il tempo e tutto sarà risolto. Buona giornata a tutti.
https://flutter.dev/docs/development/ui/advanced/splash-screen
Puoi crearlo in due modi
Ho trovato una spiegazione completa per rimuovere lo schermo bianco e visualizzare la schermata iniziale qui
SplashScreen(
seconds: 3,
navigateAfterSeconds: new MyApp(),
// title: new Text(
// 'Welcome In SplashScreen',
// style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
// ),
image: new Image.network('https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Tesla_Motors.svg/1200px-Tesla_Motors.svg.png'),
backgroundColor: Colors.white,
styleTextUnderTheLoader: new TextStyle(),
photoSize: 150.0,
loaderColor: Colors.black),
),
);