自學Flutter

137 回覆
70 Like 2 Dislike
2022-06-22 04:37:07
宜家都好少app要eject
2022-06-22 05:08:20
expo功能勁咗好多
所以我其實都諗緊,係咪真係應該學flutter
2022-06-22 05:11:23
如果個project由react寫
9成會由rn做app
business logic part 可以重用已經差好遠
2022-06-22 05:12:48
慳勁多功夫,而且rn其實run得ok快
2022-06-22 05:13:34
同埋寫bridge 都唔係咁難
不過flutter 寫bridge就真係點寫
2022-06-22 05:16:53
flutter要bridge咩?
2022-06-22 05:18:31
如果flutter要control native 野係點做
利申唔熟淨係識rn
2022-06-22 05:19:00
未學到呢part
2022-06-22 05:53:40
Native view
Flutter只有用佢個engine render嘅野先快 native view實慢
呢樣野都屌左好耐 所以如果你有野要係用到native view 你要預有機會你成個app比佢炒起 e.g. fb ads
呢d case一律建議用返rn
2022-06-22 19:21:52
點定義control native 先
基本上用method channel 已經做到好多野
但你話native view 就算啦
2022-06-24 00:59:14
今日講下點set theme先 我會用以下呢個package
https://pub.dev/packages/flex_color_scheme

可以去Theme playground 慢慢試
https://rydmike.com/flexcolorscheme/themesplayground-v5

set 1 個你鐘意嘅theme 順便加埋google font
再分別assign 去MaterialAppthemedarkTheme
之後再用shared_preferences 同 riverpod 去save同load themeMode
https://pub.dev/packages/shared_preferences
static ThemeData get lightTheme => FlexThemeData.light(
  colorScheme: const ColorScheme(
    brightness: Brightness.light,
    primary: Color(0xffc62828),
    onPrimary: Color(0xfffeeeee),
    ...
    inverseSurface: Color(0xff3d2e2d),
    onInverseSurface: Color(0xfffbeeec),
    inversePrimary: Color(0xffffb3aa),
    shadow: Color(0xff000000),
  ),
  scaffoldBackground: const Color(0xfff9f9f9),
  surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
  blendLevel: 15,
  appBarStyle: FlexAppBarStyle.background,
  tooltipsMatchBackground: true,
  tabBarStyle: FlexTabBarStyle.forBackground,
  visualDensity: FlexColorScheme.comfortablePlatformDensity,
  tones: FlexTones.vividSurfaces(Brightness.light),
  useMaterial3: true,
  fontFamily: GoogleFonts.roboto().fontFamily, // set google fonts
);

child: MaterialApp(
  title: 'Pokepedia',
  debugShowCheckedModeBanner: false,
  theme: AppTheme.lightTheme,
  darkTheme: AppTheme.darkTheme,
  themeMode: currentThemeMode, 
  ...
),
2022-06-24 01:03:53
如果你想對 themeData 有多啲控制 可以用 ThemeExtension 去define你自己嘅 Color 或者 TextTheme

下面我define咗1隻Color light mode 時係黑色, dark mode 時係白色

最後記得响 theme 度用 copyWith 加入你嘅 ThemeExtension
MaterialApp(
  theme: AppTheme.lightTheme.copyWith(
    extensions: <ThemeExtension<dynamic>>[
      CustomColors.light,
    ],
  ),
  darkTheme: AppTheme.darkTheme.copyWith(
    extensions: <ThemeExtension<dynamic>>[
      CustomColors.dark,
    ],
  ),

之後你就可以用 Theme.of(context).extension<YourThemeExtexsion>()! 去用你define 嘅ThemeExtension
final customColors = Theme.of(context).extension<CustomColors>()!;
2022-06-24 01:10:08
你亦可以用extension methods 咁就唔使再打 Theme.of(context)
extension BuildContextX on BuildContext { 
  ThemeData get theme => Theme.of(this);
  TextTheme get textTheme => theme.textTheme;
  TextTheme get primaryTextTheme => theme.primaryTextTheme; 
  ColorScheme get colorScheme => theme.colorScheme;
  CustomColors get customColors => theme.extension<CustomColors>()!;
}

Container(
  color: context.customColors.inverseTheme,
),
2022-06-24 01:51:07
由ios native + android native轉咗用flutter 因為唔想storyboard 轉swift ui 又覺得swift ui 同flutter 好似。我都喺做吓啲booking app,又感覺唔到有咩速度上嘅問題,再加上而家可以做埋網頁,其實幾爽。再加埋呢AWS+ Spring Boot,就可以出街,但係我又想研究吓firebase cloud,可唔可以加快workflow,師兄有見解嗎?
2022-06-24 15:12:19
firebase 好用,auth + db 放晒上去, 依家official doc 有埋flutter,好快可以出街
我都係swiftui 轉學flutter兩都最大分別係state management
2022-06-24 19:54:41
Performance黎講 Flutter 好過RN
同埋RN 成日有Dependncy Conflict
2022-06-24 22:04:54
SharedPreferences 係1個key value database
可以用嚟store唔重要嘅data

用以下方法去
get SharedPreferences instance
write data
read data
final sharedPreferences = await SharedPreferences.getInstance();

await sharedPreferences.setString('themeMode', 'light');

final String? themeMode = sharedPreferences.getString('themeMode');


因為SharedPreferences read data 唔係 asynchronous
我哋可以直接return ThemeMode

abstract class ISettingsRepository {
  Future<void> saveThemeMode(ThemeMode themeMode);
  ThemeMode loadThemeMode();
}


class SettingsRepository implements ISettingsRepository {
  SettingsRepository({required SharedPreferences sharedPreferences})
      : _sharedPreferences = sharedPreferences;

  final SharedPreferences _sharedPreferences;

  @override
  Future<void> saveThemeMode(ThemeMode themeMode) {    
 String stringToSave;

 switch (themeMode) {
   case ThemeMode.light:
  stringToSave = 'light';
  break;
   ...
 }

   await _sharedPreferences.setString('themeMode', stringToSave);
  }
  
  @override
  ThemeMode loadThemeMode() {    
 ThemeMode result;
 final themeMode = _sharedPreferences.getString('themeMode');

 switch (themeMode) {
   case 'light':
  result = ThemeMode.light;
  break;
   ...
   default:
  result = ThemeMode.system;
  break;
 }

 return result;
  }
}
2022-06-24 22:05:30
之後我哋整1個 StateNotifier 去manage ThemeMode
class ThemeModeStateNotifier extends StateNotifier<ThemeMode> {
  ThemeModeStateNotifier({required ISettingsRepository repository})  : _repository = repository,
        super(ThemeMode.system);

  final ISettingsRepository _repository;

  Future<void> setThemeMode(ThemeMode themeMode) async {
    state = themeMode;
    await _repository.saveThemeMode(themeMode);
  }

  void loadThemeMode() {
    state = _repository.loadThemeMode();
  }
}

第1次call themeModeStateNotifierProvider 嘅時候 會load埋 ThemeMode
final themeModeStateNotifierProvider = StateNotifierProvider<ThemeModeStateNotifier, ThemeMode>((ref) { 
  return ThemeModeStateNotifier(
    repository: ref.watch(settingsRepositoryProvider),
  )..loadThemeMode();
});

final settingsRepositoryProvider = Provider<ISettingsRepository>(
  (ref) => SettingsRepository(sharedPreferences: ref.watch(sharedPreferencesProvider)),
);
2022-06-24 22:06:09
因為 SharedPreferences.getInstance() 係 asynchronous
我哋要用 FutureProvider 咁就會return AsyncValue<SharedPreferences>
但當你要inject AsyncValue 嘅時候會好麻煩

如果唔想用 FutureProvider
我哋可以响 runApp() 之前 call SharedPreferences.getInstance() 然後再override Provider
https://stackoverflow.com/questions/68170238/riverpod-create-service-with-async-dependency-better-elegant-way

final sharedPreferencesProvider =
    Provider<SharedPreferences>((_) => throw Exception('Shared Preferences not initialized'));


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final sharedPreferences = await SharedPreferences.getInstance();
  ...
  runApp(
    ProviderScope(
      overrides: [
        sharedPreferencesProvider.overrideWithValue(sharedPreferences),
      ],
      child: const PokepediaApp(),
    ),
  );
}


最後响 MaterialApp assign ThemeMode
同埋响 settings page 用 ref.read(themeModeStateNotifierProvider.notifier).setThemeMode()
去set同save ThemeMode

final currentThemeMode = ref.watch(themeModeStateNotifierProvider);
 
MaterialApp(
  ...
  themeMode: currentThemeMode,
  ...
),

// ui
onPressed: (BuildContext context) {
ref.read(themeModeStateNotifierProvider.notifier).setThemeMode(ThemeMode.light);
},
2022-06-25 23:13:57
終於開始咗整圖鑑
搵到個pagination package幾好用
https://pub.dev/packages/infinite_scroll_pagination

而家一開始會load咗cached data先
當拉到底就會經api download多20個item

同埋開始咗學flutter animation
送上連登仔最愛嘅恥鬼

Type icon
https://github.com/duiker101/pokemon-type-svg-icons
Pokemon gif icon
https://www.deviantart.com/kattling

2022-06-26 00:10:54
想問android studio 係咪唔好用
2022-06-26 00:33:59
flutter嘅話 IDE 我見好多人都係用vs code
我自己都係 感覺多啲extension
2022-06-26 00:59:07
食ram過vs code
但好用係好用既
2022-06-27 23:21:56
試咗好耐點解 AnimatedContainer 唔work
原來我包住咗另一個 Container
2022-06-28 01:01:42
返工做code enhancement 做到懷疑人生
吹水台自選台熱 門最 新手機台時事台政事台World體育台娛樂台動漫台Apps台遊戲台影視台講故台健康台感情台家庭台潮流台美容台上班台財經台房屋台飲食台旅遊台學術台校園台汽車台音樂台創意台硬件台電器台攝影台玩具台寵物台軟件台活動台電訊台直播台站務台黑 洞