Last active
November 4, 2024 12:25
-
-
Save lukas-h/4a101ffc2e2c847a33b492a902bda896 to your computer and use it in GitHub Desktop.
Flutter Workshop 2024 Q1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:math'; | |
Future<int> asyncFunc() async { | |
final a = Future<int>.delayed(const Duration(seconds: 3), () => 10); | |
final result = await a; | |
return result; | |
} | |
Future<void> main() async { | |
/* | |
int a = 5; | |
print(a); | |
await asyncFunc(); | |
print('Hi'); | |
final list = [1, 2, 3, 4, 5]; | |
for (final element in list) { | |
print(element); | |
} | |
final stream = Stream.fromIterable([1, 2, 3, 4, 5]); | |
// blocking | |
await for (final element in stream) { | |
print(element); | |
} | |
// non-blocking | |
stream.listen((event) {});*/ | |
generatorFunction().listen(print); | |
} | |
Stream<int> generatorFunction() async* { | |
int counter = 0; | |
while (true) { | |
await Future.delayed(const Duration(seconds: 1)); | |
yield counter++; | |
} | |
} | |
Stream<int> inner(int max) async* { | |
final random = Random(); | |
while (true) { | |
await Future.delayed(const Duration(seconds: 1)); | |
yield random.nextInt(max); | |
} | |
} | |
Stream<int> randomNumberGenerator() async* { | |
yield* inner(5); | |
yield* inner(10); | |
yield* inner(15); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter_basics_workshop/cubit/auth_cubit.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
class AuthScreen extends StatelessWidget { | |
const AuthScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return BlocProvider( | |
create: (context) => AuthCubit(), | |
child: Scaffold( | |
body: Center( | |
child: BlocConsumer<AuthCubit, AuthState>( | |
listener: (context, state) { | |
debugPrint(state.runtimeType.toString()); | |
if (state is AuthException) { | |
final message = state.message; | |
showDialog( | |
context: context, | |
builder: (context) => AlertDialog( | |
content: Text('Error during login: $message'), | |
actions: [ | |
TextButton.icon( | |
onPressed: () { | |
Navigator.pop(context); | |
}, | |
icon: const Icon(Icons.check), | |
label: const Text('Ok'), | |
) | |
], | |
), | |
); | |
} | |
}, | |
builder: (context, state) => switch (state) { | |
(AuthInitial initial) => TextButton.icon( | |
icon: const Icon(Icons.login), | |
label: const Text('Login'), | |
onPressed: () { | |
context.read<AuthCubit>().loginWithEmailAndPassword('', ''); | |
}, | |
), | |
(AuthSuccess success) => Text('Success ${success.userId}'), | |
_ => const CircularProgressIndicator(), | |
}, | |
), | |
), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:bloc/bloc.dart'; | |
import 'package:equatable/equatable.dart'; | |
import 'package:flutter/material.dart'; | |
part 'auth_state.dart'; | |
class AuthCubit extends Cubit<AuthState> { | |
AuthCubit() : super(AuthInitial()); | |
Future<void> loginWithEmailAndPassword(String email, String password) async { | |
try { | |
emit(AuthLoading()); | |
// Mock login | |
emit(AuthSuccess(userId: UniqueKey().toString())); | |
await Future.delayed(const Duration(seconds: 1)); | |
final userId = UniqueKey().toString(); | |
emit(AuthSuccess(userId: userId)); | |
await Future.delayed(const Duration(seconds: 1)); | |
emit(AuthSuccess(userId: userId)); | |
emit(AuthSuccess(userId: userId)); | |
emit(AuthSuccess(userId: userId)); | |
} catch (e) { | |
emit(AuthException(message: e.toString())); | |
} | |
} | |
Future<void> logout() async { | |
emit(AuthLoading()); | |
// Mock logout | |
await Future.delayed(const Duration(seconds: 3)); | |
emit(AuthInitial()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
part of 'auth_cubit.dart'; | |
abstract class AuthState extends Equatable {} | |
class AuthInitial extends AuthState { | |
@override | |
List<Object?> get props => []; | |
} | |
class AuthLoading extends AuthState { | |
@override | |
List<Object?> get props => []; | |
} | |
class AuthException extends AuthState { | |
final String message; | |
AuthException({required this.message}); | |
@override | |
List<Object?> get props => [message]; | |
} | |
class AuthSuccess extends AuthState { | |
final String userId; | |
AuthSuccess({required this.userId}); | |
@override | |
List<Object?> get props => [userId]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:bloc/bloc.dart'; | |
class CounterCubit extends Cubit<int> { | |
CounterCubit() : super(0); | |
void increment() { | |
emit(state + 1); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
class PositionsCubit extends Cubit<List<Offset>> { | |
PositionsCubit() : super([]); | |
addPosition(Offset offset) { | |
emit([ | |
...state, | |
offset, | |
]); | |
} | |
} | |
class GestureDetectionScreen extends StatelessWidget { | |
const GestureDetectionScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: BlocProvider( | |
create: (context) => PositionsCubit(), | |
child: BlocBuilder<PositionsCubit, List<Offset>>( | |
builder: (context, state) { | |
return GestureDetector( | |
onTapDown: (details) { | |
context | |
.read<PositionsCubit>() | |
.addPosition(details.localPosition); | |
}, | |
onPanStart: (details) {}, | |
onPanUpdate: (details) {}, | |
onPanEnd: (details) {}, | |
child: Container( | |
height: 1000, | |
width: 1000, | |
color: Colors.yellow, | |
child: Stack( | |
children: [ | |
...state.map( | |
(e) => Positioned( | |
top: e.dy - 25, | |
left: e.dx - 25, | |
child: Container( | |
height: 50, | |
width: 50, | |
decoration: BoxDecoration( | |
borderRadius: BorderRadius.circular(25), | |
color: Colors.red, | |
), | |
), | |
), | |
) | |
], | |
), | |
), | |
); | |
}, | |
), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter_basics_workshop/auth_screen.dart'; | |
import 'package:flutter_basics_workshop/cubit/counter_cubit.dart'; | |
import 'package:flutter_basics_workshop/gesture_screen.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
void main() async { | |
runApp(const MaterialApp(home: GestureDetectionScreen())); | |
} | |
class StatelessScreen extends StatelessWidget { | |
const StatelessScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Example AppBar'), | |
), | |
body: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: [ | |
const Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text('Example App'), | |
Text('Example App'), | |
Text('Example App'), | |
], | |
), | |
Container( | |
color: Colors.red, | |
child: const Text('Example App'), | |
), | |
const Text('Example App'), | |
], | |
), | |
); | |
} | |
} | |
class StatefulScreen extends StatefulWidget { | |
const StatefulScreen({super.key}); | |
@override | |
State<StatefulScreen> createState() => _StatefulScreenState(); | |
} | |
enum TimerState { | |
stopped, | |
paused, | |
running, | |
} | |
class _StatefulScreenState extends State<StatefulScreen> { | |
Timer? _timer; | |
int _counter = 0; | |
TimerState _timerState = TimerState.stopped; | |
_createTimer() => Timer.periodic(const Duration(seconds: 1), (e) { | |
setState(() { | |
_counter++; | |
}); | |
}); | |
@override | |
void initState() { | |
super.initState(); | |
} | |
@override | |
void dispose() { | |
_timer?.cancel(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Column( | |
crossAxisAlignment: CrossAxisAlignment.center, | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Center( | |
child: Text( | |
'$_counter', | |
style: const TextStyle(fontSize: 30), | |
), | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
IconButton( | |
onPressed: () { | |
_timer?.cancel(); | |
if (_timerState == TimerState.paused) { | |
setState(() { | |
_timerState = TimerState.running; | |
_timer = _createTimer(); | |
}); | |
} | |
if (_timerState == TimerState.stopped) { | |
setState(() { | |
_timerState = TimerState.running; | |
_timer = _createTimer(); | |
_counter = 0; | |
}); | |
} else { | |
setState(() { | |
_timerState = TimerState.paused; | |
}); | |
} | |
}, | |
icon: _timerState == TimerState.running | |
? const Icon(Icons.pause) | |
: const Icon(Icons.play_arrow), | |
), | |
IconButton( | |
onPressed: _timerState != TimerState.stopped | |
? () { | |
setState(() { | |
_timerState = TimerState.stopped; | |
_timer?.cancel(); | |
}); | |
} | |
: null, | |
icon: const Icon(Icons.stop), | |
), | |
], | |
), | |
], | |
), | |
); | |
} | |
} | |
class BuilderExampleScreen extends StatelessWidget { | |
const BuilderExampleScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: LayoutBuilder( | |
builder: (context, constraints) { | |
return Center( | |
child: Text('${constraints.maxHeight} ${constraints.maxWidth}'), | |
); | |
}, | |
), | |
); | |
} | |
} | |
class StreamBasedTimerScreen extends StatelessWidget { | |
const StreamBasedTimerScreen({super.key}); | |
Stream<int> inner(int max) async* { | |
final random = Random(); | |
while (true) { | |
await Future.delayed(const Duration(seconds: 1)); | |
yield random.nextInt(max); | |
} | |
} | |
Stream<int> randomNumberGenerator() async* { | |
yield* inner(10); | |
yield* inner(10); | |
yield* inner(15); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Column( | |
children: [ | |
FutureBuilder( | |
future: Future.delayed(Duration.zero), | |
builder: (context, snapshot) { | |
return Container(); | |
}, | |
), | |
StreamBuilder<int>( | |
stream: randomNumberGenerator(), | |
builder: (context, snapshot) { | |
return Center(child: Text('${snapshot.data}')); | |
}, | |
), | |
], | |
), | |
); | |
} | |
} | |
class CounterCubitExampleScreen extends StatelessWidget { | |
const CounterCubitExampleScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return BlocProvider( | |
create: (context) => CounterCubit(), | |
child: Scaffold( | |
floatingActionButton: const MyFABWidget(), | |
body: BlocBuilder<CounterCubit, int>( | |
builder: (context, state) { | |
return Center(child: Text('$state')); | |
}, | |
), | |
), | |
); | |
} | |
} | |
class MyFABWidget extends StatelessWidget { | |
const MyFABWidget({ | |
super.key, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return FloatingActionButton( | |
onPressed: () { | |
context.read<CounterCubit>().increment(); | |
}, | |
child: const Icon(Icons.add), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment