Chuyển đến nội dung chính

Bài đăng

Đang hiển thị bài đăng từ Tháng 11, 2026

video_player: primitive video Flutter dựa trên platform

video_player: primitive video Flutter dựa trên platform video_player đáng chú ý vì nó giải quyết controller, khởi tạo, buffering, subtitle và lifecycle. Bài này trình bày cách đặt package vào đúng boundary của một ứng dụng Flutter production thay vì chỉ copy một snippet vào màn hình. Package này sở hữu phần nào? Giữ API của package ở một adapter hoặc feature boundary có tên rõ ràng. Đưa lifecycle, lỗi và trạng thái loading vào contract mà UI có thể kiểm thử. Chỉ expose capability cần thiết; đừng để toàn app phụ thuộc vào chi tiết triển khai. Snippet bắt đầu final controller = VideoPlayerController . networkUrl ( Uri . parse (url)); await controller. initialize (); controller. play (); return AspectRatio ( aspectRatio : controller.value.aspectRatio, child : VideoPlayer (controller), ); Checklist trước khi ship Đọc README và changelog của package đúng version đang pin. Viết một test cho lifecycle, lỗi và hành vi khi app về background. Kiểm tra Android, iO...

Very Good CLI: scaffolding Flutter có opinion

Very Good CLI: scaffolding Flutter có opinion very_good_cli đáng chú ý vì nó giải quyết template project, flavor, mặc định testing và quy ước CI. Bài này trình bày cách đặt package vào đúng boundary của một ứng dụng Flutter production thay vì chỉ copy một snippet vào màn hình. Package này sở hữu phần nào? Giữ API của package ở một adapter hoặc feature boundary có tên rõ ràng. Đưa lifecycle, lỗi và trạng thái loading vào contract mà UI có thể kiểm thử. Chỉ expose capability cần thiết; đừng để toàn app phụ thuộc vào chi tiết triển khai. Snippet bắt đầu dart pub global activate very_good_cli very_good create flutter_app my_app cd my_app very_good packages get very_good test -- coverage Checklist trước khi ship Đọc README và changelog của package đúng version đang pin. Viết một test cho lifecycle, lỗi và hành vi khi app về background. Kiểm tra Android, iOS, web hoặc desktop đúng platform mà app hỗ trợ. Ghi lại owner, upgrade cadence và kế hoạch rollback trong repo. P...

Venera: layout reader tùy chỉnh trong Flutter

App đọc trông như “chỉ là ảnh” cho tới khi page mode, RTL, zoom và pre-cache va nhau. Venera là nghiên cứu hay về layout tùy chỉnh + quản lý thư viện. Học theo Page model độc lập với page widget. Pre-cache trang kề mạnh kèm memory cap. Thư viện là local DB + nguồn remote tùy chọn. Cạm bẫy Pinch-zoom và lật trang đấu nhau; định nghĩa gesture arena sớm. Decode off UI isolate. Tham chiếu tốt khi xây viewer media scroll dài . Bài viết gốc đăng tại FlutterCook . Bản trên đó là bản được cập nhật mới nhất.

video_player: the platform-backed Flutter video primitive

video_player: the platform-backed Flutter video primitive video_player is useful because it focuses on controllers, initialization, buffering, subtitles, and lifecycle. The important engineering move is to place the package behind a clear boundary, so your Flutter UI depends on a stable capability rather than a vendor-shaped API. What the library should own Keep package calls inside a named adapter or feature boundary. Make lifecycle, errors, and loading state part of a testable contract. Expose only the capability the app needs; hide implementation details from the whole tree. A focused starting point final controller = VideoPlayerController . networkUrl ( Uri . parse (url)); await controller. initialize (); controller. play (); return AspectRatio ( aspectRatio : controller.value.aspectRatio, child : VideoPlayer (controller), ); Production checklist Read the README and changelog for the exact version you pin. Add one test for lifecycle, failure, and app...

Very Good CLI: opinionated Flutter scaffolding

Very Good CLI: opinionated Flutter scaffolding very_good_cli is useful because it focuses on project templates, flavors, testing defaults, and CI conventions. The important engineering move is to place the package behind a clear boundary, so your Flutter UI depends on a stable capability rather than a vendor-shaped API. What the library should own Keep package calls inside a named adapter or feature boundary. Make lifecycle, errors, and loading state part of a testable contract. Expose only the capability the app needs; hide implementation details from the whole tree. A focused starting point dart pub global activate very_good_cli very_good create flutter_app my_app cd my_app very_good packages get very_good test -- coverage Production checklist Read the README and changelog for the exact version you pin. Add one test for lifecycle, failure, and app background/foreground behavior. Verify every platform your product supports, not only the developer machine. Record o...

Venera: custom reader layouts in Flutter

Readers look like “just images” until page modes, RTL, zoom, and pre-cache collide. Venera is a useful study in custom layout + library management. Steal this Page model independent of page widget. Aggressive adjacent-page pre-cache with memory caps. Library as local DB + optional remote sources. Pitfalls Pinch-zoom + page turn gestures fight each other; define gesture arenas early. Decode off the UI isolate. Good reference when building any long-scroll media viewer. Originally published on FlutterCook . Read the latest version there — that copy is the one kept up to date.

url_launcher: platform intent với hợp đồng fallback

url_launcher: platform intent với hợp đồng fallback url_launcher đáng chú ý vì nó giải quyết canLaunchUrl, launch mode, web URL và handler không khả dụng. Bài này trình bày cách đặt package vào đúng boundary của một ứng dụng Flutter production thay vì chỉ copy một snippet vào màn hình. Package này sở hữu phần nào? Giữ API của package ở một adapter hoặc feature boundary có tên rõ ràng. Đưa lifecycle, lỗi và trạng thái loading vào contract mà UI có thể kiểm thử. Chỉ expose capability cần thiết; đừng để toàn app phụ thuộc vào chi tiết triển khai. Snippet bắt đầu final uri = Uri . parse ( 'mailto:support@example.com' ); if ( await canLaunchUrl (uri)) { await launchUrl (uri, mode : LaunchMode .externalApplication); } else { showUnsupportedAction (); } Checklist trước khi ship Đọc README và changelog của package đúng version đang pin. Viết một test cho lifecycle, lỗi và hành vi khi app về background. Kiểm tra Android, iOS, web hoặc desktop đúng platfor...

supabase_flutter: auth, Postgres, realtime và storage

supabase_flutter: auth, Postgres, realtime và storage supabase_flutter đáng chú ý vì nó giải quyết khởi tạo client có kiểu, auth event, RLS và lưu session. Bài này trình bày cách đặt package vào đúng boundary của một ứng dụng Flutter production thay vì chỉ copy một snippet vào màn hình. Package này sở hữu phần nào? Giữ API của package ở một adapter hoặc feature boundary có tên rõ ràng. Đưa lifecycle, lỗi và trạng thái loading vào contract mà UI có thể kiểm thử. Chỉ expose capability cần thiết; đừng để toàn app phụ thuộc vào chi tiết triển khai. Snippet bắt đầu await Supabase . initialize ( url : const String . fromEnvironment ( 'SUPABASE_URL' ), publishableKey : const String . fromEnvironment ( 'SUPABASE_KEY' ), ); final supabase = Supabase .instance.client; await supabase.auth. signInWithPassword ( email : email, password : password, ); Checklist trước khi ship Đọc README và changelog của package đúng version đang pin. Viết một...

Spotube: client nhạc Flutter ưu tiên privacy

Spotube chứng minh bạn ship được trải nghiệm nhạc bóng bẩy đa mobile/desktop từ một codebase Flutter — không cần sở hữu backend catalog. Tín hiệu stack Riverpod cho state và DI. drift cho dữ liệu thư viện bền vững. media_kit (và plugin liên quan) cho playback đa nền tảng. Release store gồm F-Droid/Flathub — packaging là một phần sản phẩm. Đáng học Tách tìm catalog khỏi thư viện local . Playback là service headless, UI chỉ là shell mỏng. Persist queue và vị trí — app nhạc bị resume liên tục. Cạm bẫy API audio nền tảng khác nhau nhiều (background mode, lock screen, Bluetooth). Ràng buộc pháp lý/ToS với catalog bên thứ ba không phải vấn đề Flutter, nhưng giết app nhanh hơn một frame jank. Dùng Spotube như bản đồ mặt phẳng plugin mà app media thật cần. Bài viết gốc đăng tại FlutterCook . Bản trên đó là bản được cập nhật mới nhất.

url_launcher: platform intent with a fallback contract

url_launcher: platform intent with a fallback contract url_launcher is useful because it focuses on canLaunchUrl, launch modes, web URLs, and unavailable handlers. The important engineering move is to place the package behind a clear boundary, so your Flutter UI depends on a stable capability rather than a vendor-shaped API. What the library should own Keep package calls inside a named adapter or feature boundary. Make lifecycle, errors, and loading state part of a testable contract. Expose only the capability the app needs; hide implementation details from the whole tree. A focused starting point final uri = Uri . parse ( 'mailto:support@example.com' ); if ( await canLaunchUrl (uri)) { await launchUrl (uri, mode : LaunchMode .externalApplication); } else { showUnsupportedAction (); } Production checklist Read the README and changelog for the exact version you pin. Add one test for lifecycle, failure, and app background/foreground behavior. Verif...

supabase_flutter: auth, Postgres, realtime, and storage

supabase_flutter: auth, Postgres, realtime, and storage supabase_flutter is useful because it focuses on typed client initialization, auth events, RLS, and session persistence. The important engineering move is to place the package behind a clear boundary, so your Flutter UI depends on a stable capability rather than a vendor-shaped API. What the library should own Keep package calls inside a named adapter or feature boundary. Make lifecycle, errors, and loading state part of a testable contract. Expose only the capability the app needs; hide implementation details from the whole tree. A focused starting point await Supabase . initialize ( url : const String . fromEnvironment ( 'SUPABASE_URL' ), publishableKey : const String . fromEnvironment ( 'SUPABASE_KEY' ), ); final supabase = Supabase .instance.client; await supabase.auth. signInWithPassword ( email : email, password : password, ); Production checklist Read the README and c...

Spotube: a privacy-minded Flutter music client

Spotube proves you can ship a polished music experience across mobile and desktop from one Flutter codebase — without owning the catalog backend. Stack signals Riverpod for state and DI. drift for durable local library data. media_kit (and related plugins) for playback across platforms. Store releases including F-Droid/Flathub — packaging is part of the product. What to steal Separate catalog search from local library state. Make playback a headless service with a thin UI shell. Persist queue and position — music apps are resumed constantly. Pitfalls Platform audio APIs differ wildly (background modes, lock screens, Bluetooth). Legal/ToS constraints around third-party catalogs are not a Flutter problem, but they will kill the app faster than a jank frame. Use Spotube as a map of the plugin surface a real media app needs. Originally published on FlutterCook . Read the latest version there — that copy is the one kept up to date.