Skip to content
Snippets Groups Projects
Commit a5636c7a authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Fix data propagation between widgets

parent 0bf5f2f5
No related branches found
No related tags found
1 merge request!45Resolve "Fix data propagation between widgets"
Pipeline #4648 passed
This commit is part of merge request !45. Comments created here will be created in the context of that merge request.
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=1.0.35 app.versionName=1.0.36
app.versionCode=36 app.versionCode=37
...@@ -11,6 +11,10 @@ class DataCubit extends HydratedCubit<DataState> { ...@@ -11,6 +11,10 @@ class DataCubit extends HydratedCubit<DataState> {
emit(state); emit(state);
} }
void updateCounter(int delta) {
emit(DataState(counter: (state.counter ?? 0) + delta));
}
@override @override
DataState? fromJson(Map<String, dynamic> json) { DataState? fromJson(Map<String, dynamic> json) {
int counter = json['counter'] as int; int counter = json['counter'] as int;
......
...@@ -2,11 +2,15 @@ import 'dart:io'; ...@@ -2,11 +2,15 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:random/config/theme.dart'; import 'package:random/config/theme.dart';
import 'package:random/cubit/bottom_nav_cubit.dart';
import 'package:random/cubit/data_cubit.dart';
import 'package:random/cubit/settings_cubit.dart';
import 'package:random/ui/skeleton.dart'; import 'package:random/ui/skeleton.dart';
void main() async { void main() async {
...@@ -38,7 +42,13 @@ class MyApp extends StatelessWidget { ...@@ -38,7 +42,13 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MultiBlocProvider(
providers: [
BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
BlocProvider<DataCubit>(create: (context) => DataCubit()),
],
child: MaterialApp(
title: 'Random application', title: 'Random application',
theme: appTheme, theme: appTheme,
home: SkeletonScreen(), home: SkeletonScreen(),
...@@ -46,6 +56,7 @@ class MyApp extends StatelessWidget { ...@@ -46,6 +56,7 @@ class MyApp extends StatelessWidget {
supportedLocales: context.supportedLocales, supportedLocales: context.supportedLocales,
locale: context.locale, locale: context.locale,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
),
); );
} }
} }
...@@ -21,7 +21,10 @@ class DemoPage extends StatelessWidget { ...@@ -21,7 +21,10 @@ class DemoPage extends StatelessWidget {
SizedBox(height: 8), SizedBox(height: 8),
AppHeader(text: 'TOP'), AppHeader(text: 'TOP'),
SizedBox(height: 20), SizedBox(height: 20),
persistedCounterBlock(), persistedCounterBlock(BlocProvider.of<DataCubit>(context)),
SizedBox(height: 20),
testBlocConsumer(),
testBlocBuilder(),
SizedBox(height: 20), SizedBox(height: 20),
fakeApiCall(), fakeApiCall(),
SizedBox(height: 20), SizedBox(height: 20),
...@@ -31,17 +34,7 @@ class DemoPage extends StatelessWidget { ...@@ -31,17 +34,7 @@ class DemoPage extends StatelessWidget {
); );
} }
Widget persistedCounterBlock() { Widget persistedCounterBlock(DataCubit dataCubit) {
return BlocProvider<DataCubit>(
create: (BuildContext context) => DataCubit(),
child: BlocBuilder<DataCubit, DataState>(
builder: (BuildContext context, DataState state) {
void updateCounter(int delta) {
BlocProvider.of<DataCubit>(context).getData(
DataState(counter: (state.counter ?? 0) + delta),
);
}
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
...@@ -49,43 +42,60 @@ class DemoPage extends StatelessWidget { ...@@ -49,43 +42,60 @@ class DemoPage extends StatelessWidget {
IconButton( IconButton(
icon: Icon(UniconsSolid.arrow_circle_down), icon: Icon(UniconsSolid.arrow_circle_down),
color: appTheme.primaryColor, color: appTheme.primaryColor,
onPressed: () => updateCounter(-1), onPressed: () => dataCubit.updateCounter(-1),
),
Padding(
padding: EdgeInsets.all(10),
child: Text(state.counter.toString()),
), ),
testBlocConsumer(),
IconButton( IconButton(
icon: Icon(UniconsSolid.arrow_circle_up), icon: Icon(UniconsSolid.arrow_circle_up),
color: appTheme.primaryColor, color: appTheme.primaryColor,
onPressed: () => updateCounter(1), onPressed: () => dataCubit.updateCounter(1),
), ),
], ],
); );
},
),
);
} }
Widget fakeApiCall() { Widget fakeApiCall() {
return BlocProvider<SettingsCubit>( return BlocBuilder<SettingsCubit, SettingsState>(
create: (BuildContext context) => SettingsCubit(), builder: (context, settingsSate) {
child: BlocBuilder<SettingsCubit, SettingsState>(
builder: (BuildContext context, SettingsState state) {
SettingsCubit settings = BlocProvider.of<SettingsCubit>(context);
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('apiUrl: ' + settings.getApiUrl()), Text('apiUrl: ' + settingsSate.apiUrl.toString()),
Text('securityToken: ' + settings.getSecurityToken()), Text('securityToken: ' + (settingsSate.securityToken.toString())),
Text('interfaceType: ' + settings.getInterfaceType().toString()), Text('interfaceType: ' + settingsSate.interfaceType.toString()),
Text('unknown: ' + settings.getSetting('unknown', 'undefined').toString()),
], ],
); );
}, },
), );
}
Widget testBlocConsumer() {
return BlocConsumer<DataCubit, DataState>(
listener: (context, dataState) {
// do stuff here based on state
},
builder: (context, dataState) {
// return widget here based on state
return Text('BlocConsumer / ' + dataState.toString());
},
);
}
Widget testBlocListener() {
return BlocListener<DataCubit, DataState>(
listener: (context, dataState) {
// do stuff here based on state
},
);
}
Widget testBlocBuilder() {
return BlocBuilder<DataCubit, DataState>(
builder: (context, dataState) {
// return widget here based on state
return Text('BlocBuilder / ' + dataState.toString());
},
); );
} }
} }
...@@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; ...@@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_swipe/flutter_swipe.dart'; import 'package:flutter_swipe/flutter_swipe.dart';
import 'package:random/cubit/bottom_nav_cubit.dart'; import 'package:random/cubit/bottom_nav_cubit.dart';
import 'package:random/cubit/settings_cubit.dart';
import 'package:random/ui/screens/about_page.dart'; import 'package:random/ui/screens/about_page.dart';
import 'package:random/ui/screens/demo_page.dart'; import 'package:random/ui/screens/demo_page.dart';
import 'package:random/ui/screens/graph_page.dart'; import 'package:random/ui/screens/graph_page.dart';
...@@ -21,8 +20,6 @@ class SkeletonScreen extends StatefulWidget { ...@@ -21,8 +20,6 @@ class SkeletonScreen extends StatefulWidget {
class _SkeletonScreenState extends State<SkeletonScreen> { class _SkeletonScreenState extends State<SkeletonScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('SkeletonScreen - build');
const List<Widget> pageNavigation = <Widget>[ const List<Widget> pageNavigation = <Widget>[
DemoPage(), DemoPage(),
GraphPage(), GraphPage(),
...@@ -30,22 +27,13 @@ class _SkeletonScreenState extends State<SkeletonScreen> { ...@@ -30,22 +27,13 @@ class _SkeletonScreenState extends State<SkeletonScreen> {
AboutPage(), AboutPage(),
]; ];
return BlocProvider<SettingsCubit>(
create: (BuildContext context) => SettingsCubit(),
child: BlocProvider<BottomNavCubit>(
create: (BuildContext context) => BottomNavCubit(),
child: BlocBuilder<BottomNavCubit, int>(
builder: (BuildContext context, int state) {
return Scaffold( return Scaffold(
extendBodyBehindAppBar: false, extendBodyBehindAppBar: false,
appBar: StandardAppBar(), appBar: StandardAppBar(),
body: Swiper( body: Swiper(
itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount, itemCount: BlocProvider.of<BottomNavCubit>(context).pagesCount,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return AnimatedSwitcher( return pageNavigation.elementAt(index);
duration: const Duration(milliseconds: 300),
child: pageNavigation.elementAt(index),
);
}, },
pagination: SwiperPagination( pagination: SwiperPagination(
builder: SwiperCustomPagination( builder: SwiperCustomPagination(
...@@ -62,9 +50,5 @@ class _SkeletonScreenState extends State<SkeletonScreen> { ...@@ -62,9 +50,5 @@ class _SkeletonScreenState extends State<SkeletonScreen> {
), ),
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
); );
},
),
),
);
} }
} }
...@@ -7,8 +7,6 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget { ...@@ -7,8 +7,6 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('StandardAppBar - build');
return AppBar( return AppBar(
title: AppHeader(text: 'app_name'), title: AppHeader(text: 'app_name'),
actions: [ actions: [
......
...@@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; ...@@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:random/cubit/data_cubit.dart';
import 'package:random/cubit/settings_cubit.dart'; import 'package:random/cubit/settings_cubit.dart';
import 'package:random/models/interface_type.dart'; import 'package:random/models/interface_type.dart';
...@@ -12,24 +13,38 @@ class AppHeader extends StatelessWidget { ...@@ -12,24 +13,38 @@ class AppHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('AppHeader - build (' + this.text + ')'); return Row(
mainAxisAlignment: MainAxisAlignment.start,
return BlocProvider<SettingsCubit>( crossAxisAlignment: CrossAxisAlignment.start,
create: (BuildContext context) => SettingsCubit(), children: [
child: BlocBuilder<SettingsCubit, SettingsState>( Text(
builder: (BuildContext context, SettingsState state) { tr(text),
SettingsCubit settings = BlocProvider.of<SettingsCubit>(context);
bool isExpert = settings.getInterfaceType() == InterfaceType.expert;
String titleSuffix = isExpert ? ' ⭐' : '';
return Text(
tr(text) + titleSuffix,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2), style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
),
SizedBox(width: 2),
expertInterfaceIndicator(),
SizedBox(width: 2),
dataCounterIndicator(),
],
);
}
Widget expertInterfaceIndicator() {
return BlocBuilder<SettingsCubit, SettingsState>(
builder: (BuildContext context, SettingsState settingsState) {
bool isExpert = settingsState.interfaceType == InterfaceType.expert;
return Text(isExpert ? '⭐' : '');
},
); );
}
Widget dataCounterIndicator() {
return BlocBuilder<DataCubit, DataState>(
builder: (context, dataState) {
return Text('(' + dataState.counter.toString() + ')');
}, },
),
); );
} }
} }
...@@ -3,7 +3,7 @@ description: A random application, for testing purpose only. ...@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
publish_to: 'none' publish_to: 'none'
version: 1.0.35+36 version: 1.0.36+37
environment: environment:
sdk: '^3.0.0' sdk: '^3.0.0'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment