First draft of Onboarding page
This commit is contained in:
37
lib/screens/onboarding/bloc/onboarding_bloc.dart
Normal file
37
lib/screens/onboarding/bloc/onboarding_bloc.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'onboarding_event.dart';
|
||||
import 'onboarding_state.dart';
|
||||
|
||||
class OnboardingBloc extends Bloc<OnboardingEvent, OnboardingState> {
|
||||
OnboardingBloc() : super(OnboardingInitial());
|
||||
|
||||
int pageIndex = 0;
|
||||
|
||||
final pageController = PageController(initialPage: 0);
|
||||
|
||||
@override
|
||||
Stream<OnboardingState> mapEventToState(
|
||||
OnboardingEvent event,
|
||||
) async* {
|
||||
if (event is PageChangedEvent) {
|
||||
if (pageIndex == 2) {
|
||||
yield NextScreenState();
|
||||
return;
|
||||
}
|
||||
pageIndex += 1;
|
||||
|
||||
pageController.animateToPage(
|
||||
pageIndex,
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.ease,
|
||||
);
|
||||
|
||||
yield PageChangedState(counter: pageIndex);
|
||||
} else if (event is PageSwipedEvent) {
|
||||
pageIndex = event.index;
|
||||
yield PageChangedState(counter: pageIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
lib/screens/onboarding/bloc/onboarding_event.dart
Normal file
16
lib/screens/onboarding/bloc/onboarding_event.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
//part of 'onboarding_bloc.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@immutable
|
||||
abstract class OnboardingEvent {}
|
||||
|
||||
class PageChangedEvent extends OnboardingEvent {
|
||||
|
||||
}
|
||||
|
||||
class PageSwipedEvent extends OnboardingEvent {
|
||||
final int index;
|
||||
|
||||
PageSwipedEvent({required this.index});
|
||||
}
|
||||
18
lib/screens/onboarding/bloc/onboarding_state.dart
Normal file
18
lib/screens/onboarding/bloc/onboarding_state.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
//part of 'onboarding_bloc.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@immutable
|
||||
abstract class OnboardingState {}
|
||||
|
||||
class OnboardingInitial extends OnboardingState {}
|
||||
|
||||
class PageChangedState extends OnboardingState {
|
||||
final int counter;
|
||||
|
||||
PageChangedState({
|
||||
required this.counter,
|
||||
});
|
||||
}
|
||||
|
||||
class NextScreenState extends OnboardingState {}
|
||||
38
lib/screens/onboarding/page/onboarding_page.dart
Normal file
38
lib/screens/onboarding/page/onboarding_page.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../bloc/onboarding_bloc.dart';
|
||||
import '../bloc/onboarding_state.dart';
|
||||
import '../widget/onboarding_content.dart';
|
||||
|
||||
class OnboardingPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: _buildBody(context),
|
||||
);
|
||||
}
|
||||
|
||||
BlocProvider<OnboardingBloc> _buildBody(BuildContext context) {
|
||||
return BlocProvider<OnboardingBloc>(
|
||||
create: (BuildContext context) => OnboardingBloc(),
|
||||
child: BlocConsumer<OnboardingBloc, OnboardingState>(
|
||||
listenWhen: (_, currState) => currState is NextScreenState,
|
||||
listener: (context, state) {
|
||||
Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute(
|
||||
builder: (_) {
|
||||
//return SignUpPage();
|
||||
return Text('Test');
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
buildWhen: (_, currState) => currState is OnboardingInitial,
|
||||
builder: (context, state) {
|
||||
return OnboardingContent();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
114
lib/screens/onboarding/widget/onboarding_content.dart
Normal file
114
lib/screens/onboarding/widget/onboarding_content.dart
Normal file
@@ -0,0 +1,114 @@
|
||||
import 'package:dots_indicator/dots_indicator.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||
|
||||
import '../../../core/const/color_constants.dart';
|
||||
import '../../../core/const/data_constants.dart';
|
||||
import '../bloc/onboarding_bloc.dart';
|
||||
import '../bloc/onboarding_event.dart';
|
||||
import '../bloc/onboarding_state.dart';
|
||||
|
||||
class OnboardingContent extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bloc = BlocProvider.of<OnboardingBloc>(context);
|
||||
return SafeArea(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: _createPageView(bloc.pageController, bloc),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _createStatic(bloc),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _createPageView(PageController controller, OnboardingBloc bloc) {
|
||||
return PageView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: controller,
|
||||
children: DataConstants.onboardingTiles,
|
||||
onPageChanged: (index) {
|
||||
bloc.add(PageSwipedEvent(index: index));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _createStatic(OnboardingBloc bloc) {
|
||||
return Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
BlocBuilder<OnboardingBloc, OnboardingState>(
|
||||
buildWhen: (_, currState) => currState is PageChangedState,
|
||||
builder: (context, state) {
|
||||
return DotsIndicator(
|
||||
dotsCount: 3,
|
||||
position: bloc.pageIndex.toDouble(),
|
||||
decorator: DotsDecorator(
|
||||
color: Colors.grey,
|
||||
activeColor: ColorConstants.primaryColor,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<OnboardingBloc, OnboardingState>(
|
||||
buildWhen: (_, currState) => currState is PageChangedState,
|
||||
builder: (context, state) {
|
||||
final percent = _getPercent(bloc.pageIndex);
|
||||
return TweenAnimationBuilder<double>(
|
||||
tween: Tween<double>(begin: 0, end: percent),
|
||||
duration: Duration(seconds: 1),
|
||||
builder: (context, value, _) => CircularPercentIndicator(
|
||||
radius: 110,
|
||||
backgroundColor: ColorConstants.primaryColor,
|
||||
progressColor: Colors.white,
|
||||
percent: 1 - value,
|
||||
center: Material(
|
||||
shape: CircleBorder(),
|
||||
color: ColorConstants.primaryColor,
|
||||
child: RawMaterialButton(
|
||||
shape: CircleBorder(),
|
||||
onPressed: () {
|
||||
bloc.add(PageChangedEvent());
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Icon(
|
||||
Icons.east_rounded,
|
||||
size: 38.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
},
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
double _getPercent(int pageIndex) {
|
||||
switch (pageIndex) {
|
||||
case 0:
|
||||
return 0.25;
|
||||
case 1:
|
||||
return 0.65;
|
||||
case 2:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
lib/screens/onboarding/widget/onboarding_tile.dart
Normal file
46
lib/screens/onboarding/widget/onboarding_tile.dart
Normal file
@@ -0,0 +1,46 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OnboardingTile extends StatelessWidget {
|
||||
final title, imagePath, mainText;
|
||||
|
||||
OnboardingTile({this.imagePath, this.mainText, this.title});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 34),
|
||||
Expanded(
|
||||
child: Image.asset(
|
||||
imagePath,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 65),
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 24.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: screenWidth / 100,
|
||||
),
|
||||
child: Text(
|
||||
mainText,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user