Проблема в том, что значки прогресса и кнопка продолжения скрыты в моем степпере (видна кнопка отмены). Поэтому, когда я нажимаю на место, где должна быть кнопка «продолжить» (рядом с кнопкой «Отмена»), происходит событие «продолжить», и оно корректно. Странно то, что когда я использую один и тот же код в новом тестовом проекте, я вижу и кнопки, и значки. Возможно, это связано с моей боковой панелью, но я не уверен.
import 'package:flutter/material.dart';
import 'package:taamin/bloc/navigation_bloc/navigation_bloc.dart';
class MyOrdersPage extends StatefulWidget with NavigationStates{
@override
_MyOrdersPageState createState() => _MyOrdersPageState();
}
class _MyOrdersPageState extends State<MyOrdersPage> {
List<Step> steps = [
Step(
title: const Text('New Account'),
isActive: true,
state: StepState.complete,
content: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: 'Email Address'),
),
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
),
],
),
),
Step(
title: const Text('Address'),
isActive: true,
state: StepState.editing,
content: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: 'Home Address'),
),
TextFormField(
decoration: InputDecoration(labelText: 'Postcode'),
),
],
),
),
Step(
state: StepState.error,
title: const Text('Avatar'),
subtitle: const Text("Error!"),
content: Column(
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.red,
)
],
),
),
];
StepperType stepperType = StepperType.vertical;
int currentStep = 0;
bool complete = false;
next() {
currentStep + 1 != steps.length
? goTo(currentStep + 1)
: setState(() => complete = true);
}
cancel() {
if (currentStep > 0) {
goTo(currentStep - 1);
}
}
goTo(int step) {
setState(() => currentStep = step);
}
switchStepType() {
setState(() => stepperType == StepperType.horizontal
? stepperType = StepperType.vertical
: stepperType = StepperType.horizontal);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Assurance Véhicule'),
),
body: Column(children: <Widget>[
complete ? Expanded(
child: Center(
child: AlertDialog(
title: new Text("Profile Created"),
content: new Text(
"Tada!",
),
actions: <Widget>[
new FlatButton(
child: new Text("Close"),
onPressed: () {
setState(() => complete = false);
},
),
],
),
),
)
: Expanded(
child: Stepper(
steps: steps,
type: stepperType,
currentStep: currentStep,
onStepContinue: next,
onStepTapped: (step) => goTo(step),
onStepCancel: cancel,
),
),
]),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.list),
onPressed: switchStepType,
),
);
}
}
и вот код моего меню боковой панели:
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:rxdart/rxdart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:taamin/bloc/navigation_bloc/navigation_bloc.dart';
import 'package:taamin/sidebar/menu_item.dart';
class SideBar extends StatefulWidget {
@override
_SideBarState createState() => _SideBarState();
}
class _SideBarState extends State<SideBar>
with SingleTickerProviderStateMixin<SideBar> {
AnimationController _animationController;
StreamController<bool> isSidebarOpenedStreamController;
Stream<bool> isSidebarOpenedStream;
StreamSink<bool> isSidebarOpenedSink;
final _animationDuration = const Duration(milliseconds: 500);
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: _animationDuration);
isSidebarOpenedStreamController = PublishSubject<bool>();
isSidebarOpenedStream = isSidebarOpenedStreamController.stream;
isSidebarOpenedSink = isSidebarOpenedStreamController.sink;
}
@override
void dispose() {
_animationController.dispose();
isSidebarOpenedStreamController.close();
isSidebarOpenedSink.close();
super.dispose();
}
void onIconPressed() {
final animationStatus = _animationController.status;
final isAnimationCompleted = animationStatus == AnimationStatus.completed;
//completed means sidebar is open
if (isAnimationCompleted) {
isSidebarOpenedSink.add(false);
_animationController.reverse();
} else {
isSidebarOpenedSink.add(true);
_animationController.forward();
}
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return StreamBuilder<bool>(
initialData: false,
stream: isSidebarOpenedStream,
builder: (context, isSideBarOpenedAsync) {
return AnimatedPositioned(
duration: _animationDuration,
top: 0,
bottom: 0,
left: isSideBarOpenedAsync.data ? 0 : -screenWidth,
right: isSideBarOpenedAsync.data ? 0 : screenWidth - 30,
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
color: const Color(0xFF262AAA),
child: Column(
children: <Widget>[
SizedBox(
height: 100,
),
ListTile(
title: Text(
"Yassine",
style: TextStyle(
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.w800),
),
subtitle: Text(
"firstname.name@gmail.com",
style: TextStyle(
color: Color(0xFF1BB5FD),
fontSize: 15,
),
),
leading: CircleAvatar(
child: Icon(
Icons.perm_identity,
color: Colors.white,
),
radius: 40,
),
),
Divider(
height: 64,
thickness: 0.5,
color: Colors.white.withOpacity(0.3),
indent: 32,
endIndent: 32,
),
MenuItem(
icon: Icons.home,
title: "Home",
onTap: () {
onIconPressed();
BlocProvider.of<NavigationBloc>(context).add(NavigationEvents.HomePageClickedEvent);
},
),
MenuItem(
icon: Icons.person,
title: "My Accounts",
onTap: () {
onIconPressed();
BlocProvider.of<NavigationBloc>(context).add(NavigationEvents.MyAccountClickedEvent);
},
),
MenuItem(
icon: Icons.directions_car,
title: "Assurance Véhicule",
onTap: () {
onIconPressed();
BlocProvider.of<NavigationBloc>(context).add(NavigationEvents.MyOrdersClickedEvent);
},
),
MenuItem(
icon: Icons.card_giftcard,
title: "Wishlist",
),
Divider(
height: 64,
thickness: 0.5,
color: Colors.white.withOpacity(0.3),
indent: 32,
endIndent: 32,
),
MenuItem(
icon: Icons.settings,
title: "Settings",
),
MenuItem(
icon: Icons.exit_to_app,
title: "Logout",
onTap: () {
onIconPressed();
exit(0);
}
),
],
),
),
),
Align(
alignment: Alignment(0, -0.9),
child: GestureDetector(
onTap: () {
onIconPressed();
},
child: ClipPath(
clipper: CustomMenuClipper(),
child: Container(
width: 35,
height: 110,
color: Color(0xFF262AAA),
alignment: Alignment.centerLeft,
child: AnimatedIcon(
progress: _animationController.view,
icon: AnimatedIcons.menu_close,
color: Color(0xFF1BB5FD),
size: 25,
),
),
),
),
)
],
),
);
},
);
}
}
class CustomMenuClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Paint paint = Paint();
paint.color = Colors.white;
final width = size.width;
final height = size.height;
Path path = Path();
path.moveTo(0, 0);
path.quadraticBezierTo(0, 8, 10, 16);
path.quadraticBezierTo(width - 1, height / 2 - 20, width, height / 2);
path.quadraticBezierTo(width + 1, height / 2 + 20, 10, height - 16);
path.quadraticBezierTo(0, height - 8, 0, height);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}