SlideShare a Scribd company logo
1 of 106
Download to read offline
台北 & ⾼雄
來體驗 bloc ⼩⽅塊
的神奇魔法
Johnny Sung (宋岡諺)
Full stack developer
⼤綱
•Bloc 介紹
•舉個例⼦寫寫看
•怎麼測試?
☕
咖啡準備好了嗎?
https://www.redbubble.com/i/ipad-case/I-turn-co
ff
ee-into-code-by-DutchArt/23986463.MNKGF
BLoC stands for Business Logic Component.
Bloc is a design pattern created by Google to help separate
business logic from the presentation layer and enable a
developer to reuse code more efficiently.
https://pub.dev/packages/
fl
utter_bloc
Bloc 元件
•Cubit
•Bloc
•BlocBuilder
Bloc 元件
•BlocBuilder
•BlocSelector
•BlocProvider
•MultiBlocProvider
•BlocListener
•MultiBlocListener
•BlocConsumer
•RepositoryProvider
•MultiRepositoryProvider
Bloc
Cubit
https://www.getreligion.org/getreligion/2019/12/12/bible-trivia-time-for-hard-working-scribes-what-is-a-cubit-a-shekel-an-ephah
cubit /kj’ubɪt/ 腕尺
(Noun.): an ancient unit of length based on
the length of the forearm.
古時⼀種量度,⾃⼿肘⾄中指端,長約 18 英⼨
https://cdict.net/q/cubit
跟這個⼀點關係都沒有。
簡單來說,
Cubit 算是 Bloc 的簡化版。
(1)
(2)
發想步驟
•列出所有可能的 事件 (Events)
•列出所有可能的 狀態 (States)
舉個例⼦
(_/)
( •_•)
/>~ 🌰
// 抽象事件
abstract class MyBlocEvent {}
// 抓成績單
class GetScoringDataEvent extends MyBlocEvent {}
// 抽象狀態
abstract class MyBlocState {}
// 微笑狀態
class SmileState extends MyBlocState {}
// 哭泣狀態
class CryingState extends MyBlocState {}
// 初始狀態
class InitState extends MyBlocState {}
// 錯誤狀態
class ErrorState extends MyBlocState {
Error error;
ErrorState(this.error);
}
import 'package:bloc/bloc.dart';
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
MyBloc() : super(InitState()) {
on<GetScoringDataEvent>((event, emit) {
emit(SmileState());
});
}
}
class ScoreRepository {
Future<int> getScore() async {
await Future.delayed(const Duration(seconds: 1)); // 等待 1 秒,模擬網路延遲
var rand = Random();
var score = rand.nextInt(100);
return score;
}
}
取成績單
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<MyScoreResponseModel> getScore() async {
final response = await http.get(
Uri.parse(constServerDomain + "/score"),
headers: defaultHeaders());
final map = json.decode(response.body);
return MyScoreResponseModel(map);
}
(未來可⽤ API 取成績單)
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
late ScoreRepository _scoreRepo;
MyBloc(MyBlocState initialState) : super(initialState) {
_scoreRepo = ScoreRepository();
}
@override
Stream<MyBlocState> mapEventToState(MyBlocEvent event) async* {
if (event is GetScoringDataEvent) {
yield InitState();
try {
int score = await _scoreRepo.getScore();
if (score >= 60) {
yield SmileState();
} else {
yield CryingState();
}
} catch (e) {
yield ErrorState();
}
}
}
}
bloc: ^7.2.0
flutter_bloc: ^7.2.0
import 'package:bloc/bloc.dart';
import 'package:bloc_demo/score_repository.dart';
import 'my_bloc_event.dart';
import 'my_bloc_state.dart';
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
late ScoreRepository _scoreRepo;
MyBloc() : super(InitState()) {
_scoreRepo = ScoreRepository();
on<GetScoringDataEvent>((event, emit) async {
try {
var value = await _scoreRepo.getScore();
if (value >= 60) {
emit(SmileState());
} else {
emit(CryingState());
}
}catch(error){
emit(ErrorState());
}
});
}
}
bloc: ^8.1.0
flutter_bloc: ^8.1.1
https://github.com/felangel/bloc/issues/2526
https://bloclibrary.dev/#/migration
import 'package:bloc/bloc.dart';
import 'package:bloc_demo/score_repository.dart';
import 'my_bloc_event.dart';
import 'my_bloc_state.dart';
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
late ScoreRepository _scoreRepo;
MyBloc() : super(InitState()) {
_scoreRepo = ScoreRepository();
on<GetScoringDataEvent>((event, emit) {
_scoreRepo.getScore().then((value) {
if (value >= 60) {
emit(SmileState());
} else {
emit(CryingState());
}
}).catchError((error) {
emit(ErrorState());
});
});
}
}
import 'package:bloc/bloc.dart';
import 'package:bloc_demo/score_repository.dart';
import 'my_bloc_event.dart';
import 'my_bloc_state.dart';
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
late ScoreRepository _scoreRepo;
MyBloc() : super(InitState()) {
_scoreRepo = ScoreRepository();
on<GetScoringDataEvent>((event, emit) async {
try {
var value = await _scoreRepo.getScore();
if (value >= 60) {
emit(SmileState());
} else {
emit(CryingState());
}
}catch(error){
emit(ErrorState());
}
});
}
}
import 'package:bloc/bloc.dart';
import 'package:bloc_demo/score_repository.dart';
import 'my_bloc_event.dart';
import 'my_bloc_state.dart';
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
late ScoreRepository _scoreRepo;
MyBloc() : super(InitState()) {
_scoreRepo = ScoreRepository();
on<GetScoringDataEvent>((event, emit) async {
try {
var value = await _scoreRepo.getScore();
if (value >= 60) {
emit(SmileState());
} else {
emit(CryingState());
}
}catch(error){
emit(ErrorState());
}
});
}
}
Bloc 主邏輯
import 'package:bloc_demo/my_bloc.dart';
import 'package:bloc_demo/score_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late MyBloc _myBloc;
@override
void initState() {
super.initState();
_myBloc = MyBloc(scoreRepo: ScoreRepository());
}
@override
void dispose() {
_myBloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
// 內容在下⼀⾴
}
}
@override
Widget build(BuildContext context) {
return BlocBuilder<MyBloc, MyBlocState>(
bloc: _myBloc,
builder: (context, state) {
if (state is SmileState) {
return const Text('😄');
} else if (state is CryingState) {
return const Text('😭');
} else if (state is ErrorState) {
return Text(state.error.toString());
}
return const CircularProgressIndicator();
});
}
⽤ BlocBuilder 來顯⽰
換⼀個真實例⼦
abstract class DataBlocEvent {}
class MyBlocLoadEvent extends DataBlocEvent {}
abstract class DataBlocState {}
class DataBlocInitialState extends DataBlocState {}
class DataBlocLoadingState extends DataBlocState {}
class DataBlocLoadedState extends DataBlocState {
final String data;
DataBlocLoadedState(this.data);
}
class DataBlocNoDataState extends DataBlocState {}
class DataBlocErrorState extends DataBlocState {
final String error;
DataBlocErrorState(this.error);
}
class MyDataBloc extends Bloc<DataBlocEvent, DataBlocState> {
MyDataBloc() : super(DataBlocInitialState()) {
on<MyBlocLoadEvent>((event, emit) async {
if (state is DataBlocLoadingState) {
return;
}
emit(DataBlocLoadingState());
try {
final data = await fetchData();
if (data == '') {
emit(DataBlocNoDataState());
} else {
emit(DataBlocLoadedState(data));
}
} catch (e) {
emit(DataBlocErrorState(e.toString()));
}
});
}
} bloc: ^8.1.0
flutter_bloc: ^8.1.1
bloc: ^7.2.0
flutter_bloc: ^7.2.0
class MyDataBloc extends Bloc<DataBlocEvent, DataBlocState> {
MyDataBloc() : super(DataBlocInitialState()) {
}
@override
Stream<DataBlocState> mapEventToState(DataBlocEvent event) async* {
if (state is DataBlocLoadingState) {
return;
}
yield DataBlocLoadingState();
try {
final data = await _fetchData();
if (data == '') {
yield DataBlocNoDataState();
} else {
yield DataBlocLoadedState(data);
}
} catch (e) {
yield DataBlocErrorState(e.toString());
}
}
}
Unit test
怎麼測試?
•Arrange – 準備,準備輸入資料與期待值
•Act – 執⾏,執⾏測試對象
•Assert – 驗證,驗證結果
單元測試原則 3A 原則
import 'package:flutter_test/flutter_test.dart';
int sum(int a, int b) {
return a + b;
}
void main() {
test('sum(1, 1) value should be 2', () {
// Arrange
int a = 1;
int b = 1;
// Act
int result = sum(a, b);
// Assert
expect(result, 2);
});
}
主程式
(待測物)
Bloc/Cubit 怎麼測試?
https://pub.dev/packages/bloc_test
https://pub.dev/packages/bloc_test
官⽅範例
思考邏輯
•實作 == 與 hashCode
•或者⽤ equatable 套件
https://pub.dev/packages/equatable
思考邏輯
•實作 == 與 hashCode
https://pub.dev/packages/equatable
思考邏輯
•改⽤ isA() 只判斷型態
https://pub.dev/packages/bloc_test
void main() {
blocTest<MyBloc, MyBlocState>(
'emits [SmileState] when GetScoringDataEvent is added',
build: () {
return MyBloc(scoreRepo: ScoreRepository());
},
act: (bloc) => bloc.add(GetScoringDataEvent()),
expect: () =>
<TypeMatcher<MyBlocState>>[isA<InitState>(), isA<SmileState>()],
);
}
https://open.spotify.com/album/0y3CDnUguGkRr3lnjD8rrV
測試時好時壞?
我說球,並不是這麼踢的
https://static-arc.appledaily.com.tw/20140622/UHJ6DEJUQCOXDNKXDRORCRCLWA/img/VRMCXKN4CGZUWQQ4TWL3NYF6TQ.jpg
http://newsimg.5054399.com/uploads/userup/1904/041A2194415.jpg
哦,那要怎麼踢?
因為你沒有辦法控制外部依賴。
怎麼辦?
把它換掉。
https://img.eservice-hk.net/upload/2018/09/27/162655_d80410cf055dac9ce4ac0dbfd0bbc976.jpg
(待測物)
Test Double
測試替⾝
Test Double
•Dummy objects are passed around but never actually used. Usually they are just
used to
fi
ll parameter lists.
•Fake objects actually have working implementations, but usually take some
shortcut which makes them not suitable for production.
•Stubs provide canned answers to calls made during the test.
•Spies are stubs that also record some information based on how they were called.
One form of this might be an email service that records how many messages it was
sent.
•Mocks: objects pre-programmed with expectations which form a speci
fi
cation of the
calls they are expected to receive.
https://martinfowler.com/articles/mocksArentStubs.html#RegularTests
Test Double
•Dummy object: 為了拿來填參數所使⽤的其實⽤不到它的空物件
(null 也算是⼀種 Dummy object)。
•Fake object: 擁有類似正式程式碼的邏輯,只是簡化實作。
•Stub: 回應固定罐頭訊息的物件。
•Spy: 是 Stub 的⼀種,會紀錄怎麼被呼叫的,⽤來驗證待測物的⾏為是
否正確。
•Mocks: 使⽤ Mock Library 動態產⽣,提供 Stub, Spy, Dummy 等功能
http://teddy-chen-tw.blogspot.com/2014/09/test-double2.html
https://martinfowler.com/articles/mocksArentStubs.html#RegularTests
Dependency Injection
https://abdelmajid-baco.medium.com/understanding-dependency-injection-with-c-7da4ad9986e9
依賴注入
Dependency Injection
•Constructor Injection
•Property Injection
•Method Injection
(DI, 依賴注入)
https://ae01.alicdn.com/kf/Hd669ca14ba1c40809de41fc53bcc96c4r/PCI-Express-to-PCI-Adapter-Card-PCIe-to-Dual-Pci-Slot-Expansion-Card-USB-3-0.jpg_Q90.jpg_.webp
主邏輯
插槽
正式程式
https://ae01.alicdn.com/kf/Hd669ca14ba1c40809de41fc53bcc96c4r/PCI-Express-to-PCI-Adapter-Card-PCIe-to-Dual-Pci-Slot-Expansion-Card-USB-3-0.jpg_Q90.jpg_.webp
主邏輯
假的程式
插槽
https://shopee.tw/PCI-%E6%95%B8%E5%AD%97%E7%87%88%E8%99%9F-
%E9%9B%BB%E8%85%A6%E4%B8%BB%E6%9D%BF%E6%95%85%E9%9A%9C%E5%B0%8F%E8%A8%BA%E6%96%B7%E5%8D%A1-%E6%B8%AC%E8%A9%A6%E5%8D%A1-
%E9%9B%BB%E8%85%A6%E9%99%A4%E9%8C%AF%E5%8D%A1-%E9%99%84%E8%AA%AA%E6%98%8E%E6%9B%B8-i.45286897.10679723263?
sp_atk=50331a4e-4049-4d31-8e57-5d0dde855783&xptdk=50331a4e-4049-4d31-8e57-5d0dde855783
https://www.ruten.com.tw/item/show?21926902268524
https://ae01.alicdn.com/kf/Hd669ca14ba1c40809de41fc53bcc96c4r/PCI-Express-to-PCI-Adapter-Card-PCIe-to-Dual-Pci-Slot-Expansion-Card-USB-3-0.jpg_Q90.jpg_.webp
假的程式
插槽
測試程式
import 'dart:math';
abstract class ScoreRepoInterface {
Future<int> getScore();
}
class ScoreRepository implements ScoreRepoInterface {
@override
Future<int> getScore() async {
await Future.delayed(const Duration(seconds: 1));
var rand = Random();
var score = rand.nextInt(100);
return score;
}
}
class StubScoreRepository implements ScoreRepoInterface {
int score;
StubScoreRepository({required this.score});
@override
Future<int> getScore() async {
return score;
}
}
插槽
正式程式 假的程式 (Stub)
https://img.ltn.com.tw/Upload/news/600/2021/07/22/3612749_1_1.jpg
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
ScoreRepoInterface scoreRepo;
MyBloc({required this.scoreRepo}) : super(InitState()) {
on<GetScoringDataEvent>((event, emit) async {
emit(InitState());
int score = await scoreRepo.getScore();
if (score >= 60) {
emit(SmileState());
} else {
emit(CryingState());
}
});
}
}
製作插槽
blocTest<MyBloc, MyBlocState>(
'emits [SmileState] when GetScoringDataEvent is added',
build: () {
ScoreRepoInterface scoreRepo = StubScoreRepository(score: 60);
return MyBloc(scoreRepo: scoreRepo);
},
act: (cubit) => cubit.add(GetScoringDataEvent()),
expect: () =>
<TypeMatcher<MyBlocState>>[isA<InitState>(), isA<SmileState>()],
);
測試 Bloc (1)
blocTest<MyBloc, MyBlocState>(
'emits [CryingState] when GetScoringDataEvent is added',
build: () {
ScoreRepoInterface scoreRepo = StubScoreRepository(score: 40);
return MyBloc(scoreRepo: scoreRepo);
},
act: (cubit) => cubit.add(GetScoringDataEvent()),
expect: () =>
<TypeMatcher<MyBlocState>>[isA<InitState>(), isA<CryingState>()],
);
測試 Bloc (2)
還好嗎?
Stream
stream /str'im/
⽔流,⼩河
(Noun.) a natural body of running water
flowing on or under the earth.
https://techcrunch.com/2009/04/27/facebook-opens-up-its-stream-api-to-developers/
https://cdict.net/q/stream
串流
Stream
Stream<int> sampleOfStream() async* {
yield 1;
yield 2;
yield 3;
yield 4;
// Do something
await Future.delayed(const Duration(seconds: 3));
yield 5;
}
再舉個例⼦
https://is4-ssl.mzstatic.com/image/thumb/Podcasts125/v4/a3/a6/b5/a3a6b53f-ac3b-26f5-8d4e-094aea97f5ed/mza_17261924418676775272.jpg/500x500bb.jpg
abstract class MyBlocState {}
class InitState extends MyBlocState {}
class NumberState extends MyBlocState {
final int number;
NumberState(this.number);
}
定義狀態 (States)
•初始狀態
•取得數字狀態
abstract class MyBlocEvent {}
class StartGettingNumberEvent extends MyBlocEvent {}
class StopGettingNumberEvent extends MyBlocEvent {}
定義事件 (Events)
•開始取數字
•停⽌取數字
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
var numberLoop = NumberLoop();
MyBloc() : super(InitState()) {
on<StartGettingNumberEvent>((event, emit) async {
if (numberLoop.isRunning()) {
return;
}
Stream<int> stream = numberLoop.numberLoop();
await for (var event in stream) {
emit(NumberState(event));
}
});
on<StopGettingNumberEvent>((event, emit) {
numberLoop.cancel();
emit(InitState());
});
}
}
import 'dart:math';
class NumberLoop {
bool _isCancelled = true;
Stream<int> numberLoop() async* {
_isCancelled = false;
var rnd = Random();
while (!_isCancelled) {
yield rnd.nextInt(10000);
await Future.delayed(const Duration(seconds: 1));
}
}
cancel() {
_isCancelled = true;
}
bool isRunning() {
return !_isCancelled;
}
}
1. 產⽣⼀個數字
2. 等待⼀秒
3. 重複 (1) 步
Stream<int> numberLoop() {
_isCancelled = false;
var rnd = Random();
return Stream.periodic(
const Duration(seconds: 1), (x) => rnd.nextInt(10000))
.takeWhile((element) => !_isCancelled);
}
Stream<int> numberLoop() async* {
_isCancelled = false;
var rnd = Random();
while (!_isCancelled) {
yield rnd.nextInt(10000);
await Future.delayed(const Duration(seconds: 1));
}
}
怎麼測試?
import 'dart:math';
abstract class NumberLoopInterface {
void cancel();
bool isRunning();
Stream<int> numberLoop();
}
class NumberLoop implements NumberLoopInterface {
bool _isCancelled = true;
@override
void cancel() {
_isCancelled = true;
}
@override
bool isRunning() {
// ...略
return !_isCancelled;
}
@override
Stream<int> numberLoop() async* {
// ...略
}
}
製作插槽 (1)
import 'package:bloc_demo2/number_loop.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MyBloc extends Bloc<MyBlocEvent, MyBlocState> {
NumberLoopInterface numberLoop;
MyBloc({required this.numberLoop}) : super(InitState()) {
on<StartGettingNumberEvent>((event, emit) async {
// ... 略
});
on<StopGettingNumberEvent>((event, emit) {
numberLoop.cancel();
});
}
}
製作插槽 (2)
import 'package:bloc_demo2/number_loop.dart';
class StubNumberLoop implements NumberLoopInterface {
List<int> numbers;
StubNumberLoop({required this.numbers});
@override
Stream<int> numberLoop() {
return Stream.fromIterable(numbers);
}
@override
void cancel() {
}
@override
bool isRunning() {
return true;
}
}
製作 Stubs
import 'package:bloc_demo2/number_loop.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('test NumberLoop', () {
var loop = StubNumberLoop(numbers: [1, 2, 3]);
expect(loop.numberLoop(), emitsInOrder([1, 2, 3]));
});
}
測試 Stubs
import 'package:bloc_demo2/my_bloc.dart';
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
blocTest('test MyBloc',
build: () {
return MyBloc(numberLoop: StubNumberLoop(numbers: [1, 2, 3]));
},
act: (bloc) => bloc.add(StartGettingNumberEvent()),
expect: () => [NumberState(1), NumberState(2), NumberState(3)]);
}
測試 Bloc
總結回顧
•學到 Bloc 元件怎麼使⽤
•定義所有的事件 (Events) 與狀態 (States)
•測試 3A 原則:Arrange, Act, Assert
•善⽤ Dependency Injection 製作插槽
•外部依賴要⽤ Test double 把它換掉
Q & A
@override
Widget build(BuildContext context) {
return FutureBuilder<int>(
future: fetchData(),
initialData: 0,
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data! >= 60) {
return const Text('😄');
} else {
return const Text('😭');
}
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
return const CircularProgressIndicator();
}
});
}
@override
Widget build(BuildContext context) {
return BlocBuilder<MyBloc, MyBlocState>(
bloc: _myBloc,
builder: (context, state) {
if (state is SmileState) {
return const Text('😄');
} else if (state is CryingState) {
return const Text('😭');
} else if (state is ErrorState) {
return Text(state.error.toString());
}
return const CircularProgressIndicator();
});
}
BlocBuilder FutureBuilder
Q1: BlocBuilder 跟 FutureBuilder 的差異?
@override
Widget build(BuildContext context) {
return BlocBuilder<MyBloc, MyBlocState>(
bloc: _myBloc,
builder: (context, state) {
if (state is NumberState) {
return Text(state.number.toString());
}
return const Text('- - - -');
});
}
@override
Widget build(BuildContext context) {
return StreamBuilder<int>(initialData: null,
stream: _numberLoop.numberLoop(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return const Text('- - - -');
});
}
BlocBuilder StreamBuilder
Q2: BlocBuilder 跟 StreamBuilder 的差異?
https://github.com/j796160836/bloc_demo
範例 1
https://github.com/j796160836/bloc_demo2
範例 2

More Related Content

What's hot

Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Scott Wlaschin
 
Efficient Use of indexes in MySQL
Efficient Use of indexes in MySQLEfficient Use of indexes in MySQL
Efficient Use of indexes in MySQLAleksandr Kuzminsky
 
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang) [Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang) Johnny Sung
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
An Introduction to Gradle for Java Developers
An Introduction to Gradle for Java DevelopersAn Introduction to Gradle for Java Developers
An Introduction to Gradle for Java DevelopersKostas Saidis
 
Implementing DDD with C#
Implementing DDD with C#Implementing DDD with C#
Implementing DDD with C#Pascal Laurin
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootJosué Neis
 
우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈용근 권
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스Arawn Park
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainersSunghyouk Bae
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹Johnny Sung
 
Clean architectures with fast api pycones
Clean architectures with fast api   pyconesClean architectures with fast api   pycones
Clean architectures with fast api pyconesAlvaro Del Castillo
 
SpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSLSpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSLSunghyouk Bae
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency InjectionTheo Jungeblut
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기경원 이
 
GameplayKit으로 상태표시 UI 쉽게 만들기
GameplayKit으로 상태표시 UI 쉽게 만들기GameplayKit으로 상태표시 UI 쉽게 만들기
GameplayKit으로 상태표시 UI 쉽게 만들기Soojin Ro
 
Tips about hibernate with spring data jpa
Tips about hibernate with spring data jpaTips about hibernate with spring data jpa
Tips about hibernate with spring data jpaThiago Dos Santos Hora
 
Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022Sam Brannen
 

What's hot (20)

Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013
 
Efficient Use of indexes in MySQL
Efficient Use of indexes in MySQLEfficient Use of indexes in MySQL
Efficient Use of indexes in MySQL
 
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang) [Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
 
Spring boot
Spring bootSpring boot
Spring boot
 
An Introduction to Gradle for Java Developers
An Introduction to Gradle for Java DevelopersAn Introduction to Gradle for Java Developers
An Introduction to Gradle for Java Developers
 
Implementing DDD with C#
Implementing DDD with C#Implementing DDD with C#
Implementing DDD with C#
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
 
우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
 
Clean architectures with fast api pycones
Clean architectures with fast api   pyconesClean architectures with fast api   pycones
Clean architectures with fast api pycones
 
SpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSLSpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSL
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency Injection
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
 
GameplayKit으로 상태표시 UI 쉽게 만들기
GameplayKit으로 상태표시 UI 쉽게 만들기GameplayKit으로 상태표시 UI 쉽게 만들기
GameplayKit으로 상태표시 UI 쉽게 만들기
 
Tips about hibernate with spring data jpa
Tips about hibernate with spring data jpaTips about hibernate with spring data jpa
Tips about hibernate with spring data jpa
 
Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022
 
JavaScript Inheritance
JavaScript InheritanceJavaScript Inheritance
JavaScript Inheritance
 

Similar to [Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022

How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023Shengyou Fan
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Bkbiet day2 & 3
Bkbiet day2 & 3Bkbiet day2 & 3
Bkbiet day2 & 3mihirio
 
JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試Simon Su
 
當ZK遇見Front-End
當ZK遇見Front-End當ZK遇見Front-End
當ZK遇見Front-End祁源 朱
 
はじめてのUnitTest XCTestに触れて
はじめてのUnitTest XCTestに触れてはじめてのUnitTest XCTestに触れて
はじめてのUnitTest XCTestに触れてKenji Tanaka
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e bigAndy Peterson
 
Sbt職人のススメ
Sbt職人のススメSbt職人のススメ
Sbt職人のススメ潤一 加藤
 
Open Source Ajax Solution @OSDC.tw 2009
Open Source Ajax  Solution @OSDC.tw 2009Open Source Ajax  Solution @OSDC.tw 2009
Open Source Ajax Solution @OSDC.tw 2009Robbie Cheng
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Google App Engine Developer - Day4
Google App Engine Developer - Day4Google App Engine Developer - Day4
Google App Engine Developer - Day4Simon Su
 
Cross platform Mobile development on Titanium
Cross platform Mobile development on TitaniumCross platform Mobile development on Titanium
Cross platform Mobile development on TitaniumYiguang Hu
 
Sqladria 2009 SRC
Sqladria 2009 SRCSqladria 2009 SRC
Sqladria 2009 SRCtepsum
 
Scale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricScale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricChris Dufour
 
Visual Component Testing -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
Visual Component Testing  -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...Visual Component Testing  -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
Visual Component Testing -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...Applitools
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript EverywherePascal Rettig
 
Bootiful Development with Spring Boot and React - RWX 2017
Bootiful Development with Spring Boot and React - RWX 2017Bootiful Development with Spring Boot and React - RWX 2017
Bootiful Development with Spring Boot and React - RWX 2017Matt Raible
 
Test Infected Presentation
Test Infected PresentationTest Infected Presentation
Test Infected Presentationwillmation
 

Similar to [Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022 (20)

How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Bkbiet day2 & 3
Bkbiet day2 & 3Bkbiet day2 & 3
Bkbiet day2 & 3
 
JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試
 
Spock
SpockSpock
Spock
 
當ZK遇見Front-End
當ZK遇見Front-End當ZK遇見Front-End
當ZK遇見Front-End
 
はじめてのUnitTest XCTestに触れて
はじめてのUnitTest XCTestに触れてはじめてのUnitTest XCTestに触れて
はじめてのUnitTest XCTestに触れて
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
Sbt職人のススメ
Sbt職人のススメSbt職人のススメ
Sbt職人のススメ
 
Open Source Ajax Solution @OSDC.tw 2009
Open Source Ajax  Solution @OSDC.tw 2009Open Source Ajax  Solution @OSDC.tw 2009
Open Source Ajax Solution @OSDC.tw 2009
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Pdxpugday2010 pg90
Pdxpugday2010 pg90Pdxpugday2010 pg90
Pdxpugday2010 pg90
 
Google App Engine Developer - Day4
Google App Engine Developer - Day4Google App Engine Developer - Day4
Google App Engine Developer - Day4
 
Cross platform Mobile development on Titanium
Cross platform Mobile development on TitaniumCross platform Mobile development on Titanium
Cross platform Mobile development on Titanium
 
Sqladria 2009 SRC
Sqladria 2009 SRCSqladria 2009 SRC
Sqladria 2009 SRC
 
Scale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricScale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App Fabric
 
Visual Component Testing -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
Visual Component Testing  -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...Visual Component Testing  -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
Visual Component Testing -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
Bootiful Development with Spring Boot and React - RWX 2017
Bootiful Development with Spring Boot and React - RWX 2017Bootiful Development with Spring Boot and React - RWX 2017
Bootiful Development with Spring Boot and React - RWX 2017
 
Test Infected Presentation
Test Infected PresentationTest Infected Presentation
Test Infected Presentation
 

More from Johnny Sung

[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023Johnny Sung
 
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023Johnny Sung
 
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020Johnny Sung
 
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Johnny Sung
 
談談 Android constraint layout
談談 Android constraint layout談談 Android constraint layout
談談 Android constraint layoutJohnny Sung
 
炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作Johnny Sung
 
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹Johnny Sung
 
炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建Johnny Sung
 
About Mobile Accessibility
About Mobile AccessibilityAbout Mobile Accessibility
About Mobile AccessibilityJohnny Sung
 
Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人Johnny Sung
 
First meet with Android Auto
First meet with Android AutoFirst meet with Android Auto
First meet with Android AutoJohnny Sung
 
Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇
Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇
Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇Johnny Sung
 
[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 AccessibilityJohnny Sung
 
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇Johnny Sung
 
A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)Johnny Sung
 
uPresenter, the story.
uPresenter, the story.uPresenter, the story.
uPresenter, the story.Johnny Sung
 
Android Wear Development
Android Wear DevelopmentAndroid Wear Development
Android Wear DevelopmentJohnny Sung
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Johnny Sung
 
Android workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phoneAndroid workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phoneJohnny Sung
 
Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統Johnny Sung
 

More from Johnny Sung (20)

[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
 
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
 
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
 
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
 
談談 Android constraint layout
談談 Android constraint layout談談 Android constraint layout
談談 Android constraint layout
 
炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作
 
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
 
炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建
 
About Mobile Accessibility
About Mobile AccessibilityAbout Mobile Accessibility
About Mobile Accessibility
 
Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人
 
First meet with Android Auto
First meet with Android AutoFirst meet with Android Auto
First meet with Android Auto
 
Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇
Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇
Everything About Bluetooth (淺談藍牙 4.0) - Peripheral 篇
 
[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility
 
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
 
A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)
 
uPresenter, the story.
uPresenter, the story.uPresenter, the story.
uPresenter, the story.
 
Android Wear Development
Android Wear DevelopmentAndroid Wear Development
Android Wear Development
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101
 
Android workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phoneAndroid workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phone
 
Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統
 

Recently uploaded

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022