Skip to content

Instantly share code, notes, and snippets.

@lukas-h
Last active November 4, 2024 12:25
Show Gist options
  • Save lukas-h/4a101ffc2e2c847a33b492a902bda896 to your computer and use it in GitHub Desktop.
Save lukas-h/4a101ffc2e2c847a33b492a902bda896 to your computer and use it in GitHub Desktop.
Flutter Workshop 2024 Q1
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);
}
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(),
},
),
),
),
);
}
}
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());
}
}
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];
}
import 'package:bloc/bloc.dart';
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() {
emit(state + 1);
}
}
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,
),
),
),
)
],
),
),
);
},
),
),
);
}
}
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