correction overlay didacticiel
Origine du problème (BoxConstraints forces an infinite width / RenderPhysicalShape) :
Hauteur non bornée dans le Positioned :
Lorsque la bulle d'aide était positionnée via Positioned(top: ..., bottom: null), Flutter transmettait une contrainte de hauteur infinie (maxHeight: double.infinity).
Le bouton ElevatedButton calcule son ombre et sa forme physique via RenderPhysicalShape en appelant constraints.biggest ; avec une dimension infinie, Flutter générait une contrainte invalide (BoxConstraints(w=Infinity, 50.0<=h<=Infinity)) et crashait le rendu (ce qui provoquait l'écran gris/noir).
Nids de Row imbriqués dans le pied de la carte d'étape.
Solutions apportées :
tutorial_overlay.dart
:
Hauteur maximale bornée : _buildTooltip calcule et transmet désormais la hauteur disponible réelle de l'écran (availableHeight) via ConstrainedBox(maxHeight: available).
Bouton moderne Material 3 : Remplacement par FilledButton pour le bouton d'action principale ("Suivant" / "C'est parti").
Structure simplifiée : Aplatissement de la barre inférieure avec un Row unique utilisant Spacer().
full_app_render_test.dart
:
Ajout d'un test d'intégration complet validant le démarrage de l'application et la navigation étape par étape du didacticiel.
This commit is contained in:
@@ -124,4 +124,62 @@ void main() {
|
||||
// Aucune cible : pas de main animée non plus.
|
||||
expect(find.byType(TutorialHand), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('l\'overlay se rend correctement dans un Navigator push modal',
|
||||
(WidgetTester tester) async {
|
||||
final targetKey = GlobalKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Builder(
|
||||
builder: (context) => Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
SizedBox(key: targetKey, width: 200, height: 60),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
PageRouteBuilder<void>(
|
||||
opaque: false,
|
||||
pageBuilder: (routeCtx, _, __) => TutorialOverlay(
|
||||
steps: [
|
||||
const TutorialStep(
|
||||
title: 'Bienvenue',
|
||||
description: 'Texte introductif',
|
||||
),
|
||||
TutorialStep(
|
||||
targetKey: targetKey,
|
||||
title: 'Bouton',
|
||||
description: 'Texte bouton',
|
||||
gesture: TutorialGesture.tap,
|
||||
),
|
||||
],
|
||||
onFinished: () => Navigator.of(routeCtx).pop(),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('Ouvrir'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Ouvrir'));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
expect(find.text('Bienvenue'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Suivant'));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(find.text('Bouton'), findsOneWidget);
|
||||
expect(find.byType(TutorialHand), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user