diff --git a/lib/page/home/home_page.dart b/lib/page/home/home_page.dart index a064f7a2..91a4146c 100644 --- a/lib/page/home/home_page.dart +++ b/lib/page/home/home_page.dart @@ -6,6 +6,7 @@ import 'package:survey/model/survey_model.dart'; import 'package:survey/page/home/home_state.dart'; import 'package:survey/page/home/home_view_model.dart'; import 'package:survey/page/home/widget/home_header_widget.dart'; +import 'package:survey/page/home/widget/home_surveys_indicators_widget.dart'; import 'package:survey/page/home/widget/home_surveys_page_view_widget.dart'; import 'package:survey/usecase/get_cached_surveys_use_case.dart'; import 'package:survey/usecase/get_surveys_use_case.dart'; @@ -29,6 +30,8 @@ class HomePage extends ConsumerStatefulWidget { } class _HomePageState extends ConsumerState { + final _currentSurveysPage = ValueNotifier(0); + @override void initState() { super.initState(); @@ -67,6 +70,11 @@ class _HomePageState extends ConsumerState { if (shouldEnablePagination) ref.read(homeViewModelProvider.notifier).loadSurveysFromApi() }, + currentSurveysPage: _currentSurveysPage, + ), + HomeSurveysIndicatorsWidget( + surveysAmount: surveys.length, + currentSurveysPage: _currentSurveysPage, ), SafeArea( child: HomeHeaderWidget( @@ -84,4 +92,10 @@ class _HomePageState extends ConsumerState { content: Text(errorMessage), )); } + + @override + void dispose() { + _currentSurveysPage.dispose(); + super.dispose(); + } } diff --git a/lib/page/home/widget/home_surveys_indicators_widget.dart b/lib/page/home/widget/home_surveys_indicators_widget.dart new file mode 100644 index 00000000..6a43761f --- /dev/null +++ b/lib/page/home/widget/home_surveys_indicators_widget.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:page_view_dot_indicator/page_view_dot_indicator.dart'; +import 'package:survey/resource/dimens.dart'; + +class HomeSurveysIndicatorsWidget extends StatelessWidget { + final int surveysAmount; + final ValueNotifier currentSurveysPage; + + const HomeSurveysIndicatorsWidget({ + Key? key, + required this.surveysAmount, + required this.currentSurveysPage, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: const SizedBox.shrink(), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: Dimens.space15), + child: ValueListenableBuilder( + valueListenable: currentSurveysPage, + builder: (context, int currentSurveysPage, child) => + PageViewDotIndicator( + currentItem: currentSurveysPage, + count: surveysAmount, + selectedColor: Colors.white, + unselectedColor: Colors.white.withOpacity(0.2), + size: const Size(Dimens.homeSurveysIndicatorsSize, + Dimens.homeSurveysIndicatorsSize), + unselectedSize: const Size(Dimens.homeSurveysIndicatorsSize, + Dimens.homeSurveysIndicatorsSize), + margin: const EdgeInsets.symmetric(horizontal: Dimens.space5), + padding: EdgeInsets.zero, + alignment: Alignment.centerLeft, + fadeEdges: false, + ), + ), + ), + SizedBox(height: Dimens.space170), + ], + ); + } +} diff --git a/lib/page/home/widget/home_surveys_item_widget.dart b/lib/page/home/widget/home_surveys_item_widget.dart index d1b6d326..90bccd87 100644 --- a/lib/page/home/widget/home_surveys_item_widget.dart +++ b/lib/page/home/widget/home_surveys_item_widget.dart @@ -68,7 +68,10 @@ class HomeSurveysItemWidget extends StatelessWidget { elevation: 0, shape: const CircleBorder(), backgroundColor: Colors.white, - minimumSize: Size(Dimens.space56, Dimens.space56), + minimumSize: Size( + Dimens.homeSurveysNextButtonSize, + Dimens.homeSurveysNextButtonSize, + ), ), onPressed: onNextButtonPressed, ), diff --git a/lib/page/home/widget/home_surveys_page_view_widget.dart b/lib/page/home/widget/home_surveys_page_view_widget.dart index 09fff49f..9bef5e09 100644 --- a/lib/page/home/widget/home_surveys_page_view_widget.dart +++ b/lib/page/home/widget/home_surveys_page_view_widget.dart @@ -5,11 +5,13 @@ import 'package:survey/page/home/widget/home_surveys_item_widget.dart'; class HomeSurveysPageViewWidget extends StatelessWidget { final List surveys; final VoidCallback loadMoreSurveys; + final ValueNotifier currentSurveysPage; final _pageController = PageController(); HomeSurveysPageViewWidget({ required this.surveys, required this.loadMoreSurveys, + required this.currentSurveysPage, }); @override @@ -27,6 +29,9 @@ class HomeSurveysPageViewWidget extends StatelessWidget { }, ); }, + onPageChanged: (int index) { + currentSurveysPage.value = index; + }, ); } } diff --git a/lib/page/login/login_page.dart b/lib/page/login/login_page.dart index 907b4a78..322c4135 100644 --- a/lib/page/login/login_page.dart +++ b/lib/page/login/login_page.dart @@ -8,7 +8,7 @@ import 'package:survey/gen/assets.gen.dart'; import 'package:survey/navigator.dart'; import 'package:survey/page/login/login_state.dart'; import 'package:survey/page/login/login_view_model.dart'; -import 'package:survey/page/login/widget/text_input_forgot_password_widget.dart'; +import 'package:survey/page/login/widget/login_text_input_forgot_password_widget.dart'; import 'package:survey/resource/dimens.dart'; import 'package:survey/usecase/login_use_case.dart'; import 'package:survey/widget/circular_progress_bar_widget.dart'; @@ -86,7 +86,7 @@ class _LoginPageState extends ConsumerState { hintText: AppLocalizations.of(context)!.loginPassword, isPasswordInput: true, controller: _passwordController, - endWidget: TextInputForgotPasswordWidget( + endWidget: LoginTextInputForgotPasswordWidget( onPressed: () { _navigateToResetPassword(); }, diff --git a/lib/page/login/widget/text_input_forgot_password_widget.dart b/lib/page/login/widget/login_text_input_forgot_password_widget.dart similarity index 86% rename from lib/page/login/widget/text_input_forgot_password_widget.dart rename to lib/page/login/widget/login_text_input_forgot_password_widget.dart index 9107e073..3794f5da 100644 --- a/lib/page/login/widget/text_input_forgot_password_widget.dart +++ b/lib/page/login/widget/login_text_input_forgot_password_widget.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -class TextInputForgotPasswordWidget extends StatelessWidget { +class LoginTextInputForgotPasswordWidget extends StatelessWidget { final VoidCallback onPressed; - const TextInputForgotPasswordWidget({ + const LoginTextInputForgotPasswordWidget({ Key? key, required this.onPressed, }) : super(key: key); diff --git a/lib/resource/dimens.dart b/lib/resource/dimens.dart index 76f1a1c2..496193cc 100644 --- a/lib/resource/dimens.dart +++ b/lib/resource/dimens.dart @@ -2,12 +2,21 @@ class Dimens { Dimens._(); static const double space4 = 4; - static const double space10 = 10; + static const double space5 = 5; static const double space12 = 12; - static const double space14 = 14; + static const double space15 = 15; static const double space20 = 20; static const double space24 = 24; - static const double space56 = 56; static const double space110 = 110; static const double space120 = 120; + static const double space170 = 170; + + static const double textInputHeight = 56; + static const double textInputBorderRadius = 12; + + static const double customButtonBorderRadius = 10; + static const double customButtonHeight = 56; + + static const double homeSurveysIndicatorsSize = 8; + static const double homeSurveysNextButtonSize = 56; } diff --git a/lib/widget/custom_button_widget.dart b/lib/widget/custom_button_widget.dart index c1622028..26bbbd4e 100644 --- a/lib/widget/custom_button_widget.dart +++ b/lib/widget/custom_button_widget.dart @@ -15,13 +15,14 @@ class CustomButtonWidget extends StatelessWidget { Widget build(BuildContext context) { return SizedBox( width: double.infinity, - height: Dimens.space56, + height: Dimens.customButtonHeight, child: TextButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.white), shape: MaterialStateProperty.all( RoundedRectangleBorder( - borderRadius: BorderRadius.circular(Dimens.space10), + borderRadius: + BorderRadius.circular(Dimens.customButtonBorderRadius), ), ), ), diff --git a/lib/widget/text_input_widget.dart b/lib/widget/text_input_widget.dart index a6783760..3286f9d8 100644 --- a/lib/widget/text_input_widget.dart +++ b/lib/widget/text_input_widget.dart @@ -18,11 +18,11 @@ class TextInputWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - height: Dimens.space56, + height: Dimens.textInputHeight, padding: const EdgeInsets.symmetric(horizontal: Dimens.space12), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), - borderRadius: BorderRadius.circular(Dimens.space12), + borderRadius: BorderRadius.circular(Dimens.textInputBorderRadius), ), child: Row( children: [ diff --git a/pubspec.lock b/pubspec.lock index bd6b6457..16700b56 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -462,6 +462,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + page_view_dot_indicator: + dependency: "direct main" + description: + name: page_view_dot_indicator + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" path: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 2ec73a26..55b309fd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,6 +39,7 @@ dependencies: intl: ^0.17.0 japx: ^2.0.4 json_annotation: ^4.6.0 + page_view_dot_indicator: ^2.0.1 retrofit: ^3.0.1+1 rxdart: ^0.27.7 shared_preferences: ^2.0.15