SlideShare a Scribd company logo
1 of 65
Flutter Provider
看似簡單卻⼜不簡單的
狀態管理⼯具
Kaohsiung
Johnny Sung
Full stack developer
Johnny Sung (宋岡諺)
https://fb.com/j796160836
https://blog.jks.co
ff
ee/
https://www.slideshare.net/j796160836
https://github.com/j796160836
https://pub.dev/packages/provider
講在 Provider 之前
— InheritedWidget
Kaohsiung
https://www.youtube.com/watch?v=Zbm3hjPjQMk
在 Flutter 的世界裡...
萬物皆 Widget
在對應的狀態產⽣對應的畫⾯
https://abhishekdoshi26.medium.com/deep-dive-into-
fl
utter-trees-542f7395df5c
Widget 兄弟其實還少⼀個
• StatefulWidget
• StatelessWidget
• InheritedWidget 就是我啦!
InheritedWidget
想解決
Widget tree 跨層傳遞資料 不便的問題
https://docs.
fl
utter.dev/data-and-backend/state-mgmt/simple
class FrogColor extends InheritedWidget {
const FrogColor({
super.key,
required this.color,
required super.child,
});
final Color color;
static FrogColor? maybeOf(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<FrogColor>();
}
static FrogColor of(BuildContext context) {
final FrogColor? result = maybeOf(context);
assert(result != null, 'No FrogColor found in context');
return result!;
}
@override
bool updateShouldNotify(FrogColor oldWidget) => color != oldWidget.color;
}
https://api.
fl
utter.dev/
fl
utter/widgets/InheritedWidget-class.html
背後宣告
// continuing from previous example...
class MyPage extends StatelessWidget {
const MyPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: FrogColor(
color: Colors.green,
child: Builder(
builder: (BuildContext innerContext) {
return Text(
'Hello Frog',
style: TextStyle(color: FrogColor.of(innerContext).color),
);
},
),
),
);
}
}
https://api.
fl
utter.dev/
fl
utter/widgets/InheritedWidget-class.html
呼叫使⽤
Provider
就是 InheritedWidget 的延伸(與包裝)
其實
不信?讓我們看看⼀⼩段 Provider 的原始碼
class FrogColor extends InheritedWidget {
const FrogColor({
super.key,
required this.color,
required super.child,
});
final Color color;
static FrogColor? maybeOf(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<FrogColor>();
}
static FrogColor of(BuildContext context) {
final FrogColor? result = maybeOf(context);
assert(result != null, 'No FrogColor found in context');
return result!;
}
@override
bool updateShouldNotify(FrogColor oldWidget) => color != oldWidget.color;
}
https://api.
fl
utter.dev/
fl
utter/widgets/InheritedWidget-class.html
(剛剛看到的段落)
class Provider<T> extends InheritedProvider<T> {
Provider({
Key? key,
required Create<T> create,
Dispose<T>? dispose,
bool? lazy,
TransitionBuilder? builder,
Widget? child,
}) : super(
key: key,
lazy: lazy,
builder: builder,
create: create,
dispose: dispose,
debugCheckInvalidValueType: kReleaseMode
? null
: (T value) =>
Provider.debugCheckInvalidValueType?.call<T>(value),
child: child,
);
static T of<T>(BuildContext context, {bool listen = true}) {
assert(
context.owner!.debugBuilding ||
listen == false ||
debugIsInInheritedProviderUpdate,
'''
Tried to listen to a value exposed with provider, from outside of the widget tree. … 略
''',
);
final inheritedElement = _inheritedElementOf<T>(context);
if (listen) {
context.dependOnInheritedWidgetOfExactType<_InheritedProviderScope<T?>>();
}
final value = inheritedElement?.value;
if (_isSoundMode) {
if (value is! T) {
throw ProviderNullException(T, context.widget.runtimeType);
}
return value;
}
return value as T;
}
}
Provider 的原始碼
Provider 家族
• Provider:提供遠端存取的服務
• ChangeNoti
fi
erProvider:它會監聽 model 的變化。當資料發⽣變更,它會重繪
Consumer 的⼦ widget。
• FutureProvider:是 FutureBuilder 的⼀個封裝,提供⼀個 Future,FutureProvider 會在 Future 完成的時候
通知 Consumer 重繪它的 Widget ⼦樹。
• StreamProvider:是 StreamBuilder 的⼀個封裝,提供⼀個 Stream,然後 Consumer 會在 Stream 收到事
件時更新它的 Widget⼦樹。
import 'package:flutter/foundation.dart';
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider<Counter>(
create: (context) => Counter(),
child: Builder(builder: (context) {
final counter = context.watch<Counter>().count;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$counter'),
ElevatedButton(
onPressed: () {
final counter = context.read<Counter?>();
counter?.increment();
print('count=${counter?.count ?? 0}');
},
child: const Text('Push me')),
],
),
);
}),
),
);
}
}
Consumer<Counter>(builder: (context, myModel, child) {
return Text('${myModel.count}');
}),
或
三種寫法都可以
註:Consumer 的部份
Text('${context.watch<Counter>().count}')
Text('${Provider.of<Counter>(context).count}')
或
/// Exposes the [read] method.
extension ReadContext on BuildContext {
T read<T>() {
return Provider.of<T>(this, listen: false);
}
}
Provider 原始碼中
context.read() 對應到 Provider.of()
選單按鈕
分⾴內⾴
import 'package:flutter/foundation.dart';
class TabProvider with ChangeNotifier {
int _currentIndex = 0;
int get currentIndex => _currentIndex;
set currentIndex(int index) {
_currentIndex = index;
notifyListeners();
}
}
mixin & with
Mixins are a way of reusing a class’s code in multiple class hierarchies.
簡單來說就是:
我提供⼀些⽅法給你使⽤,但我不⽤成為你的⽗類別。
mixin ShowName {
void showName() {
print('mixin ShowName');
}
}
class Quadrilateral with ShowName {
void showAllSideLength() {
showName();
}
}
https://ithelp.ithome.com.tw/articles/10268368?sc=iThelpR
import 'package:flutter/material.dart';
import 'package:flutter_provider_tab_demo/tab_provider.dart';
import 'package:flutter_provider_tab_demo/tab_screen.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => TabProvider()),
],
child: TabScreen(),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_provider_tab_demo/tab_provider.dart';
import 'package:provider/provider.dart';
class TabItem {
final String name;
final int index;
TabItem(this.name, this.index);
}
class TabScreen extends StatelessWidget {
final List<TabItem> tabItems = [
TabItem('Tab 1', 0),
TabItem('Tab 2', 1),
TabItem('Tab 3', 2),
];
TabScreen({super.key});
@override
Widget build(BuildContext context) {
// build
}
}
return Scaffold(
appBar: AppBar(
title: const Text('Tab Example'),
),
body: Column(
children: [
ListView.builder(
shrinkWrap: true,
itemCount: tabItems.length,
itemBuilder: (context, index) {
TabItem tabItem = tabItems[index];
return ListTile(
title: Text(tabItem.name),
onTap: () {
TabProvider p = context.read<TabProvider>();
p.currentIndex = tabItem.index;
},
);
},
),
Expanded(
child: IndexedStack(
index: context.watch<TabProvider>().currentIndex,
children: const [
Center(child: Text('Tab 1')),
Center(child: Text('Tab 2')),
Center(child: Text('Tab 3')),
],
),
),
],
),
);
選單按鈕
分⾴內⾴
Provider 使⽤情境
• 會員帳號權限管理
• 帳號登入
• Token 過期、被強迫登出
• Widget tree 平⾏傳遞資料 (例如:分⾴切換)
全域的狀態機變數
Provider 我的理解:
全域變數
雖可恥但有⽤
https://stackover
fl
ow.com/questions/73226745/
fl
utter-many-bloc-providers-cluttering-widget-tree
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BlocProvider<SigninCubit>(
create: (context) => SigninCubit(),
child: BlocProvider<UpdateCubit>(
create: (context) => UpdateCubit(),
child: BlocProvider<ProfileBloc>(
create: (context) => ProfileBloc(),
child: BlocProvider<VoteBloc>(
create: (context) => VoteBloc(),
child: BlocProvider<MessageBloc>(
create: (context) => MessageBloc(),
child: BlocProvider<LeaderboardBloc>(
create: (context) => LeaderboardBloc(),
child: BlocProvider<CommentBloc>(
create: (context) => CommentBloc(),
child: BlocProvider<EditbioCubit>(
create: (context) => EditbioCubit(),
child: BlocProvider<CommentCubit>(
create: (context) => CommentCubit(),
child: BlocProvider<SearchBloc>(
create: (context) => SearchBloc(),
child: BlocProvider<SwipeBloc>(
create: (context) => SwipeBloc(),
child: Scaffold(
body: Builder(builder: (context) {
return const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Sample'),
],
),
);
}),
),
),
),
),
),
),
),
),
),
),
),
),
);
不免俗的,Flutter 沒寫好的話,很容易寫出⼀堆波動拳
https://captown.capcom.com/zh-TW/museums/street
fi
ghter/5/images/125#group=0&photo=0
部分的波動拳可以⽤ MultiXXXProvider 解決部分的問題
但這範例還有權責不明確問題
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiBlocProvider(
providers: [
BlocProvider<SigninCubit>(create: (context) => SigninCubit()),
BlocProvider<UpdateCubit>(create: (context) => UpdateCubit()),
BlocProvider<ProfileBloc>(create: (context) => ProfileBloc()),
BlocProvider<VoteBloc>(create: (context) => VoteBloc()),
BlocProvider<MessageBloc>(create: (context) => MessageBloc()),
BlocProvider<LeaderboardBloc>(create: (context) => LeaderboardBloc()),
BlocProvider<CommentBloc>(create: (context) => CommentBloc()),
BlocProvider<EditbioCubit>(create: (context) => EditbioCubit()),
BlocProvider<CommentCubit>(create: (context) => CommentCubit()),
BlocProvider<SearchBloc>(create: (context) => SearchBloc()),
BlocProvider<SwipeBloc>(create: (context) => SwipeBloc()),
],
child: Scaffold(
body: Builder(builder: (context) {
return const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Sample'),
],
),
);
}),
),
),
);
要慎⽤呀!
https://pic1.zhimg.com/80/v2-5af8d68f267c1ed3ece59d5bd919a870_1440w.webp
解決波動拳⼩建議
• View 分類好封裝進 StatelessWidget
• 邏輯與 View 分類分開存放
• ⽤ MultiProvider 或 MultiBlocProvider 等類似套件來拉平
Q: Provider 與 Bloc 有什麼差異?
我的回答:要解決的問題不同,使⽤不同的解決⽅式
當 Bloc 遇上 provider ?
http://teddy-chen-tw.blogspot.com/2012/03/blog-post_20.html
爭什麼,摻在⼀起做成撒尿⽜丸啊
https://pub.dev/packages/
fl
utter_bloc
https://pub.dev/packages/
fl
utter_bloc
😜
BlocProvider = Bloc + Provider
BlocProvider 家族
• BlocProvider
• BlocBuilder
• BlocListener
• BlocConsumer = BlocBuilder +
BlocListener
BlocProvider<LoginBloc>(
create: (BuildContext context) => LoginBloc()),
child: …,
),
在 Widget Tree 最頂層處使⽤ BlocProvider 並宣告⾃訂的 Bloc
(以下是⼀些 pseudo code)
BlocProvider 使⽤⽅式 (1/4)
BlocBuilder<LoginBloc, LoginState>(builder: (context, state) {
if (state is LoginStateLoggedIn) {
return …;
}
if (state is LoginStateInitial) {
return …;
}
return Container();
}
在所需 Widget 的 build() 處使⽤ BlocBuilder
(以下是⼀些 pseudo code)
BlocProvider 使⽤⽅式 (2/4)
這裡沒指定 bloc 參數時,預設會 Provider 往上找
在需要聆聽事件的地⽅使⽤ BlocListener
(以下是⼀些 pseudo code)
BlocProvider 使⽤⽅式 (3/4)
這裡沒指定 bloc 參數時,預設會 Provider 往上找
BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
if (state is LoginStateError) {
// Do Something
}
if (state is LoginStateLoggedIn) {
// Do Something
}
},
child: … );
在需要變更狀態的地⽅使⽤ context.read() 並操作 Bloc
(以下是⼀些 pseudo code)
BlocProvider 使⽤⽅式 (4/4)
ElevatedButton(
child: const Text('Login'),
onPressed: () {
context.read<LoginBloc>().add(LoginEventLogin());
},
)
https://docs.
fl
utter.dev/data-and-backend/state-mgmt/simple
Q&A
其他狀態管理比較
Kaohsiung
https://k.sina.cn/article_7407912364_1b98bc5ac00101jqaw.html?from=cul
https://pub.dev/packages/mobx
mobx_codegen
https://pub.dev/packages/scoped_model
https://pub.dev/packages/get
https://pub.dev/packages/riverpod
感謝聆聽

More Related Content

What's hot

Android Navigation Component
Android Navigation ComponentAndroid Navigation Component
Android Navigation ComponentŁukasz Ciupa
 
Declarative UIs with Jetpack Compose
Declarative UIs with Jetpack ComposeDeclarative UIs with Jetpack Compose
Declarative UIs with Jetpack ComposeRamon Ribeiro Rabello
 
Angular 4 The new Http Client Module
Angular 4 The new Http Client ModuleAngular 4 The new Http Client Module
Angular 4 The new Http Client Modulearjun singh
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introductionJonathan Holloway
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux IntroductionNikolaus Graf
 
Introduction to React JS for beginners | Namespace IT
Introduction to React JS for beginners | Namespace ITIntroduction to React JS for beginners | Namespace IT
Introduction to React JS for beginners | Namespace ITnamespaceit
 
Swift UI - Declarative Programming [Pramati Technologies]
Swift UI - Declarative Programming [Pramati Technologies]Swift UI - Declarative Programming [Pramati Technologies]
Swift UI - Declarative Programming [Pramati Technologies]Pramati Technologies
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기경원 이
 
React JS: A Secret Preview
React JS: A Secret PreviewReact JS: A Secret Preview
React JS: A Secret Previewvaluebound
 
Introducing Swagger
Introducing SwaggerIntroducing Swagger
Introducing SwaggerTony Tam
 
Analysing in depth work manager
Analysing in depth work managerAnalysing in depth work manager
Analysing in depth work managerbhatnagar.gaurav83
 
Introduction to Swagger
Introduction to SwaggerIntroduction to Swagger
Introduction to SwaggerKnoldus Inc.
 
Collections in Java
Collections in JavaCollections in Java
Collections in JavaKhasim Cise
 

What's hot (20)

Android Navigation Component
Android Navigation ComponentAndroid Navigation Component
Android Navigation Component
 
Declarative UIs with Jetpack Compose
Declarative UIs with Jetpack ComposeDeclarative UIs with Jetpack Compose
Declarative UIs with Jetpack Compose
 
Angular 4 The new Http Client Module
Angular 4 The new Http Client ModuleAngular 4 The new Http Client Module
Angular 4 The new Http Client Module
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
Introduction to React JS for beginners | Namespace IT
Introduction to React JS for beginners | Namespace ITIntroduction to React JS for beginners | Namespace IT
Introduction to React JS for beginners | Namespace IT
 
Swift UI - Declarative Programming [Pramati Technologies]
Swift UI - Declarative Programming [Pramati Technologies]Swift UI - Declarative Programming [Pramati Technologies]
Swift UI - Declarative Programming [Pramati Technologies]
 
Angular Lifecycle Hooks
Angular Lifecycle HooksAngular Lifecycle Hooks
Angular Lifecycle Hooks
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
 
React JS: A Secret Preview
React JS: A Secret PreviewReact JS: A Secret Preview
React JS: A Secret Preview
 
Introducing Swagger
Introducing SwaggerIntroducing Swagger
Introducing Swagger
 
React hooks
React hooksReact hooks
React hooks
 
React js
React jsReact js
React js
 
Analysing in depth work manager
Analysing in depth work managerAnalysing in depth work manager
Analysing in depth work manager
 
Introduction to Swagger
Introduction to SwaggerIntroduction to Swagger
Introduction to Swagger
 
Swagger UI
Swagger UISwagger UI
Swagger UI
 
SQLITE Android
SQLITE AndroidSQLITE Android
SQLITE Android
 
React native
React nativeReact native
React native
 
Collections in Java
Collections in JavaCollections in Java
Collections in Java
 
Simple React Todo List
Simple React Todo ListSimple React Todo List
Simple React Todo List
 

Similar to Flutter Provider - A Simple Yet Powerful State Management Tool

Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02rhemsolutions
 
Force Flutter to Rebuild or Redraw All Widgets.pptx
Force Flutter to Rebuild or Redraw All Widgets.pptxForce Flutter to Rebuild or Redraw All Widgets.pptx
Force Flutter to Rebuild or Redraw All Widgets.pptxFlutter Agency
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersJiaxuan Lin
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfKaty Slemon
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & WebkitQT-day
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widgetTudor Barbu
 
React & The Art of Managing Complexity
React &  The Art of Managing ComplexityReact &  The Art of Managing Complexity
React & The Art of Managing ComplexityRyan Anklam
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkIndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Frameworkvhazrati
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin componentsPeter Lehto
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
SoftShake 2013 - Vaadin componentization
SoftShake 2013 - Vaadin componentizationSoftShake 2013 - Vaadin componentization
SoftShake 2013 - Vaadin componentizationNicolas Fränkel
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 

Similar to Flutter Provider - A Simple Yet Powerful State Management Tool (20)

Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02
 
Mobile Application Development class 006
Mobile Application Development class 006Mobile Application Development class 006
Mobile Application Development class 006
 
Force Flutter to Rebuild or Redraw All Widgets.pptx
Force Flutter to Rebuild or Redraw All Widgets.pptxForce Flutter to Rebuild or Redraw All Widgets.pptx
Force Flutter to Rebuild or Redraw All Widgets.pptx
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for Beginners
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & Webkit
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
React & The Art of Managing Complexity
React &  The Art of Managing ComplexityReact &  The Art of Managing Complexity
React & The Art of Managing Complexity
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin components
 
GWT MVP Case Study
GWT MVP Case StudyGWT MVP Case Study
GWT MVP Case Study
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
SoftShake 2013 - Vaadin componentization
SoftShake 2013 - Vaadin componentizationSoftShake 2013 - Vaadin componentization
SoftShake 2013 - Vaadin componentization
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 

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
 
[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
 
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022Johnny 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 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹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
 

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
 
[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)
 
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
 
與 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 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
 
炎炎夏日學 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
 

Flutter Provider - A Simple Yet Powerful State Management Tool