Bài đăng

Đang hiển thị bài đăng từ 2021

Flutter 7.2 - TabBar & BottomNavigationBar

 1, Tab bar:  class _TabScreenState extends State<TabScreen> { @override Widget build (BuildContext context) { return DefaultTabController ( length: 2 , // số tab child: Scaffold ( appBar: AppBar ( title: Text ( 'Meals' ) , bottom: TabBar ( tabs: [ Tab ( icon: Icon (Icons. category ) , text: 'Category' , ) , Tab ( icon: Icon (Icons. star ) , text: 'Favorites' , ) , ] , ) , ) , body: TabBarView ( children: [ CategoriesScreen () , FavoritesScreen () , ] , ) , )) ; } } 2, BottomNavigationBar class _TabScreenState extends State<TabScreen> { final List<Map<String , Object>> _pages = [ { 'title' : 'Categor...

Connect adb

1. cd [location]\Sdk\platform-tools 2. adb devices 3. adb tcpip 5555 4. adb connect [yourDeviceIP] Nếu xảy ra lỗi " No connection could be made because the target machine actively refused it " : 1. stay connect via USB 2. connect to your WIFI network (computer and mobile device both) 3.ping DeviceIP (must be have ping to your device) 4. adb kill-server 5.adb usb 6.adb tcpip 5555 *unplug usb cable (as per @captain_majid 's comment) 7. adb connect [yourDeviceIP] 8. adb devices (must be see two device names , one of them is by deviceIP) 9. unplug USB cable  In my case: E: cd androidsdk\Sdk\platform-tools adb devices adb tcpip 5555 adb connect [yourDeviceIP]

Flutter 7.1 - Navigating to a new page, GridView, Pass data by routes, Pop data

Hình ảnh
 1, Grid view: @override Widget build (BuildContext context) { return Scaffold ( appBar: AppBar ( title: const Text ( 'DeliMeal' ) , ) , body: GridView ( // cross ngang, main d ọ c. N ế u có quá nhi ề u item thì dùng GridView.buider s ẽ t ố i ư u performance h ơ n children: DUMMY_CATEGORIES .map((catData) => CategoriesItem ( catData. title , catData. color , )) .toList() , padding: const EdgeInsets . all ( 20 ) , gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent ( // xác đ ị nh chi ề u r ộ ng t ố i đa c ủ a gridview maxCrossAxisExtent: 200 , // chi ề u r ộ ng t ố i đa c ủ a 1 item childAspectRatio: 3 / 2 , // t ỉ l ệ 2 c ạ nh item crossAxisSpacing: 20 , // kho ả ng cách gi ữ a các item theo chi ề u ngang mainAxisSpacing: 20 , // kho ả ng cách gi ữ a các item theo chi ề u d ọ c ) , ) , ) ; } 2, Navigating to ...

Flutter 6.3 - Constructor key ?

Hình ảnh
Constructor key: const TransactionItem({ Key? key , required this . transaction , required this . deleteTx , }) : super (key: key) ; Mọi StatefulWidget trong flutter đều cần có key, Stateless có thể k cần. Trong một số trường hợp, key luôn phải có. Ví dụ: Nếu k có key, khi xóa 1 item trong list view, Widget tree sẽ hiểu là đã xóa 1 item, nhưng element tree thì ko, nó sẽ so sánh các item cùng hạng tree, sau đó đẩy item ở vị trí số 2 lên đầu => set value của item 2 trong widget tree cho item đầu trong element tree (ko set lại màu mè,...). Sau khi set lại value widget tree sang element tree thì element tree sẽ xóa các item, state thừa của nó => xóa sai item. Khi có key, flutter sẽ dựa vào key để xóa, update,.. item trong element tree => xóa đúng item. Ví dụ: const TransactionItem({ Key? key , required this . transaction , required this . deleteTx , }) : super (key: key) ; *Chỉ nên dùng key khi dùng ListView, StatefulWidget. Ko nên dùng nếu k cần vì nếu dùng khi k cần ...

Flutter 6.2 - Widget lifecycler, App lifecycler, Context ?

Hình ảnh
1, Widget Lifecycler Stateful Widgets:  initState() : chỉ chạy 1 lần đầu tiên, khi widget rebuild, initState() ko đc chạy lại. Dùng để gán dữ liệu ban đầu. setState() : dùng để update và rebuild widget  didUpateWidget() : khi widget đc rebuild xong. Dùng để update lại các value thay đổi. dispose() : khi widge gone. Dùng để clean data, close connection,... tránh leak memory. Khi UI thay đổi : ví dụ khi show/hide BottomSheet constructor của widget sẽ đc gọi lại để check sự thay đổi. Vì state ko thay đổi nên ko đc gọi lại. Sau khi call constructor widget thì sẽ đến hàm didUpdateWidget. 2, App lifecycler inactive : Ko hoạt động, user ko nhìn thấy app. App rơi vào trạng thái này khi chuẩn bị running in background (paused) và chuẩn bị quay trở lại hoạt động (resumed). paused : Khi app running in background. resumed : Khi app bắt đầu visible vào chuẩn bị ng dùng có thể thao tác tới app. suspending : Khi clear app in background. class _MyHomePageState extends State<MyHomePage> w...

Flutter 6.1 - How flutter build widget ?

Hình ảnh
  1, How flutter, rebuilds or repaints the screen: Giải thích nôm na cho dễ hiểu :v chứ để hiểu rõ thì khó giải thích bằng văn bản @@ Khi build flutter app, flutter sẽ build ra 3 loại tree bao gồm : widget tree, element tree, render tree. Widget tree: code thuần túy của bạn Element tree: liên kết các widget với các object,... tạm hiểu là chuyển ngôn ngữ code sang ngôn ngữ máy. Render tree: Render những liên kết ở element tree lên màn hình. Example:  - Trong widget tree có những object nào thì khi build element tree và render tree cũng có những object đó. - Widget tree: khi bạn setSate() ở MyStateful  thì widget tree sẽ tạo ra 1 đối tượng MyStateful mới. Tuy nhiên, element tree sẽ ko tạo ra 1 MyStateful  mới mà sẽ xem xét những gì thay đổi sau khi setSate() và update lại vào element tree => Render tree. *Khi các object, value thay đổi => widget tree đều phải tạo ra 1 đối tượng mới và elemen tree sẽ xem xét sự thay đổi của widget tree => update lại lên elemen...

Flutter 5.1 - Responsive & Adaptive

 1, Cách tính height, width widget: - Khai báo 1 biến đựng widget : Ví dụ:  final appBar = AppBar ( // khai báo appBar đ ể có th ể l ấ y chi ề u cao c ủ a appbar : appBar.preferredSize title: Text ( 'Personal Expenses' ) , actions: [ // btn add ở thanh appbar IconButton ( onPressed: () { _startAddNewTransaction(context) ; } , icon: Icon (Icons. add ) , ) , ] , ) ; - Lấy chiều cao bằng cách :  appBar. preferredSize . height 2, Height, witdh màn hình: MediaQuery. of (context). size . height MediaQuery. of (context). size . width Ngoài ra còn tính đc pixel, padding,... bằng cách  MediaQuery. of (context).*something* *Nên tạo biến mediaQuery sử dụng lại để ko phải khởi tạo nhiều lần => hiệu suất kém Chỉ sử dụng mediaQuery khi thực sự cần thiết, nên tách các widget cần sử dụng đến mediaQuery sang 1 class riêng để tránh rebuild ... (giải thích rõ hơn ở bài sau). final mediaQuery = MediaQuery. of (context) ; 3, Set portrai...

Flutter 4.6 - Some array method

1. forEach() Function này giúp chúng ta lấy ra được từng phần tử ở trong danh sách từ vị trí đầu tiên đến vị trí cuối cùng. Ở ví dụ bên dưới, chúng ta print ra lần lượt các phần tử đó trên terminal. DART var fruits = [‘banana’ , ‘pineapple’ , ‘watermelon’] ; fruits. forEach ((fruit) => print(fruit)) ; // => banana pineapple watermelon 2. map() Function này giúp chúng ta tạo một danh sách mới sau khi chuyển đổi từng element trong một danh sách cho trước. Ở ví dụ bên dưới, chúng ta có được một danh sách mới và gán giá trị đó sang cho biến mappedFruits. DART var mappedFruits = fruits.map((fruit) => ‘I love $fruit’).toList() ; print (mappedFruits) ; // => ['I love banana', ‘I love pineapple’, ‘I love watermelon’] 3. contains() Function này giúp chúng ta kiểm tra để xác nhận rằng element đó có nằm trong danh sách hay không. Nếu có thì chương trình sẽ trả về true và ngược lại trả về false. DART var numbers = [ 1 , 3 , 2 , 5 , 4 ] ; print (numbe rs.cont ains( 2 )) ; // =...

Flutter 4.5 - Custom theme, font, image

Hình ảnh
 1, Custom theme:  return MaterialApp ( title: 'Personal Expenses' , theme: ThemeData ( primarySwatch: Colors. deepPurple , accentColor: Colors. amber ) , home: MyHomePage () , ) ; Use: color: Theme. of (context). primaryColor , 2, Custom font - Add fonts vào thư mục assets/fonts - Khai báo fonts ở pubspec.yaml ( Lưu ý: khoảng cách đầu ở  pubspec.yaml rất quan trọng, nếu thò thụt ko đúng sẽ gây ra lỗi hoặc không thể sử dụng đc dependence vừa thêm ko đúng) - Defind textTheme và appBarTheme ở main.dart theme: ThemeData ( primarySwatch: Colors. deepPurple , accentColor: Colors. amber , fontFamily: 'Quicksand' , textTheme: ThemeData . light (). textTheme .copyWith( headline6: TextStyle ( fontFamily: 'OpenSans' , fontSize: 18 , ) , ) , appBarTheme: AppBarTheme ( textTheme: ThemeData . light (). textTheme .copyWith( headline6: TextStyle ( fontFamily: 'OpenSans'...

Flutter 4.4 - Column SingleChildScrollView , ListView, ListView.builder()

Hình ảnh
SingleChildScrollView dùng để cuộn column Column và SingleChildScrollView:  ListView: có thể cuộn mà ko cần SingleChildScrollView  ListView.builder(): So sánh các 3 loại cuộn trên: ListView tương đương với Column + SingleChildScrollView: đều có thể cuộn, nhưng sẽ load hết các item lên view => hiệu năng kém (giống ListView trong android) ListView.builder(); chỉ load những item hiển thị lên màn hình  => tăng hiệu năng (Giống vs RecyclerView trong android)

Flutter 4.3 - String Interpolation ${expression}

Hình ảnh
 - Bạn có thể lấy giá trị của một biểu thức bên trong một chỗi (phép nội suy - interpolation)  bằng cách sử dụng  ${expression} Example: var greeting = "Hello"; var person = "Rohan"; print("${greeting}, ${person}!"); // prints "Hello, Rohan!" int x = 5; print("There are ${x < 10 ? "a few" : "many"} people in this room"); Note: để sử dụng dấu $ trong flutter mà ko bị hiểu là interpolation : print('\$ 64') => prints "$ 64"

Flutter 4.2 - Column, Row, Container

Hình ảnh
 1, Trục của column và row: Ex: mainAxisAlignment: MainAxisAlignment. spaceAround , crossAxisAlignment: CrossAxisAlignment. stretch , 2, Sự khác biệt giữa container và column, row: - 1 container chỉ có thể chứa 1 widget (text, button,...), còn column, row có thể chứa nhiều widget - Sử dụng container thì có thể custom đc nhiều style (viền, bo, margin, padding, ...) còn column, row thì không - Container có thể điều chỉnh width, height dễ dàng,... còn column, row luôn chiếm width, height nhiều nhất có thể => Tóm lại: Dùng container khi cần custom style, align Dùng row/ column khi nhiều widgets cạnh nhau Kết hợp cả container, column, row để đc cả 2 yếu tố trên :lmao

Flutter 4.1 - Những widget quan trọng

Hình ảnh
MaterialApp / CupertinoApp Typically the root widget in your app Does a lot of “behind-the-scenes” setup work for your app Allows you to configure a global theme for your app Sets up navigation behavior (e.g. animations) for your app Scaffold / CupertinoPageScaffold Typically used as a frame for a page in your app Provides a background, app bar, navigation tabs, etc Only use one scaffold per page! Container Extremely versatile widget! Can be sized (width, height, maxWidth, maxHeight), styled (border, color, shape, …) and more Can take a child (but doesn’t have to) which you also can align in different ways You’ll use this widget quite often Row / Column Must-use if you need multiple widgets sit next to each other horizontally or vertically Limited styling options => Wrap with a Container (or wrap child widgets) to apply styling Children can be aligned along main-axis and cross-axis (see separate cheat sheet Flexible / Expanded Also see separate cheat sheet attached to lecture about ...