Flutter

Flutter, Bài 4: Cài đặt Flutter SDK và Android Studio plugin

Sau những bài về Dart cơ bản, từ bây giờ chúng ta sẽ tiến vào “quần tháo” với Flutter. Trong bài này, tôi sẽ hướng dẫn các bạn cài đặt Flutter SDK, cấu hình đường dẫn vào PATH và thiết lập Android Studio. Bạn cũng có thể sử dụng JetBrain’s IntelliJ IDEA hay Visual Studio Code để viết Flutter, nhưng tốt nhất bạn nên dùng Android Studio, một phần là vì đại đa số độc giả của EITGUIDE đều có Android Studio sẵn trên máy, phần khác là sau này, tôi sẽ hướng dẫn các bạn gọi native platform API trên Android (và iOS), và dĩ nhiên, việc suggest code Android chỉ khả dụng trên Android Studio hoặc IntelliJ IDEA mà thôi.

Flutter

1. Cài đặt Flutter SDK và cấu hình PATH:

Bạn tải Flutter SDK ứng với hệ điều hành của mình về tại trang chính của Flutter ở đây. Sau đó, bạn giải nén phần SDK vào nơi bạn muốn. Để cho dễ thì bạn nên cho nó nằm ngang hàng với Android Sdk cho thuận tiện. Xong xuôi, bạn sẽ cấu hình PATH với tên variable name là PATH trỏ tới đường dẫn vào SDK. Nếu bạn cảm nhấy nhức mắt ù tai khi nghe cụm “cấu hình PATH”, bạn tham khảo bài viết này của tôi trước rồi quay lại đây sau. Lưu ý: Nếu bạn vẫn đang “cố tình” dùng VS Code, bạn cần ANDROID_HOME trong PATH trỏ tới Android Sdk của bạn.

Riêng với macOS vốn là nền tảng duy nhất có thể code ứng dụng iOS: Bạn cần có Xcode và cấu hình iOS SDK.

2. Thiết lập Android Studio:

Dĩ nhiên, bạn phải khởi động Android Studio lên. Trong phần Settings/Plugin, bạn tìm tới Install from repo và cài đặt Flutter và Dart plugins. Sau đó, bạn close hết các projects rồi restart Android Studio là xong. Tương tự, bạn có thể làm y chang với IntelliJ IDEA vốn là “chỗ dựa” của Android Studio. Sau khi Android Studio đã được khởi động lại, bạn sẽ thấy thêm một tùy chọn mới ở vùng bên phải, là Create Flutter Project. Bạn chọn vào đó để tạo một Flutter project và làm theo những hướng dẫn dù mới nhưng quen thuộc.

AS_Flutter

Nếu project đã khởi tạo thành công, bạn sẽ tạm dừng việc viết code ở đây. Tôi sẽ thay đổi tư duy của bạn để bạn có thể suy nghĩ về việc dựng giao diện của ứng dụng Flutter vì công việc này khá khác biệt so với việc dựng giao diện trên ứng dụng Android và iOS “kinh điển” và cả React Native nữa.

3. Hướng tư duy về dựng giao diện:

Đầu tiên, Flutter render giao diện bằng bộ engine của nó, với hệ thống Widgets của nó và runtime cũng của nó luôn, không như React Native vốn cho bạn dựng giao diện bằng JSX Widget giống HTML nhưng thực chất, khi biên dịch là nó gọi các Widgets của hệ thống đích, chẳng hạn, ScrollView của React Native sẽ gọi tới ScrollView của Android và UIScrollView của iOS. Ngoài ra, tương tự như React Native, nó chỉ có duy nhất một Activity trên Android hay ViewController trên iOS, việc (mang lại cảm giác) chuyển sang “màn hình” khác mà bạn thấy thực chất chỉ là nó dựng thêm Widgets chồng lên “màn hình” hiện tại để tạo cảm giác, vốn cũng là tập hợp các Widgets.

Thứ hai, bạn không thể “xì tin” lại vị trí giao diện trực tiếp trên các Widgets như android:layout_margin và android:padding trên Android, constraints trên iOS hay CSS-like rules margin và padding trên một số Component giao diện trên React Native được đâu! Muốn đặt vị đối tượng Flutter Widget nào cho chính xác, bạn phải bọc nó trong một hoặc nhiều tầng Widget chuyên chứa (Container, tương đương *Layout trong Android hay <View> trong React Native) như Center, Column, Row, Expanded, Container, Flex, v.v…

Thứ ba, bạn cũng không thể trực tiếp “xì tai” lại các thuộc tính của các Widgets như android:textColor như Android, hay CSS-like rule color trong ReactNative Text, hay trực tiếp đổi các attrs trong StoryBoard của iOS đâu. Bạn sẽ phải “thuê” thêm các class khác, có khi lại là class trong class trong attr – thường có tên là style, và có thể các Flutter Widgets khác nhau yêu cầu các class về Style khác nhau, như Text yêu cầu style là một instance của class TextStyle. Nhưng cũng có nhiều styles chẳng hạn background, bạn lại phải thao tác trực tiếp tên Widget. Do vậy, sẽ gây ức chế cho bạn ở một mức độ nào đó, và bạn cần làm nhiều thì mới thích nghi được. Dẫu sao, việc thích nghi này so ra cũng đáng lắm, tương quan với những gì Flutter đem lại.

Thứ tư, bạn không thao tác kiểu “widget nhận event sẽ gọi widget khác” như với Android hay iOS SDKs. Chẳng hạn, để update một (UI)TextView khi một (UI)Button được click, bạn chỉ cần lấy cái (UI)TextView đó, cho update phần text và việc này sẽ được code trong onClick(View) của Android hay buttonDidTap của iOS. Nhưng với Flutter, bạn sẽ phải tìm hiểu khái niệm “state” – vốn đã quen thuộc với các bạn làm việc với React và React Native. Nhưng chưa hết đâu, việc truyền tham số trực tiếp trong constructor ứng với mỗi “màn hình” rất tương đồng với props trong framework của Facebook, và bạn cũng có routing nữa.

Nhưng việc dùng state cũng đáng, vì khi bạn gán một field object vào một event của một Widget rồi, chẳng hạn một List vào một ListView rồi, thì tự cái ListView sẽ thay đổi khi List gốc thay đổi, khá khác biệt (và ít phiền phức) hơn khi làm việc với ListView hay RecyclerView, vốn bạn chỉ và phải thao tác với một Adapter, phải gọi notifyDataSetChanged mỗi khi List gốc có thay đổi, và phải định vị được index khi sửa, xóa, và chèn phần tử mới vào vị trí khác cuối. Rõ ràng, Flutter hay hơn.

Vậy, tương ứng với hành động lấy text của một EditText hay UITextField trên Flutter là gì? Có thể, bạn sẽ tạo một temp field member dạng String và update nó liên tục với event onChanged. Bạn đang đúng rồi, nhưng sẽ hay hơn nếu bạn sử dụng Controller, cụ thể hơn là TextEditingController. Về chi tiết thì tôi sẽ nói cụ thể trong bài viết về TextField.

Trên Android, việc lưu giá trị các biến vào Bundle savedInstanceState là điều hầu như lúc nào cũng có khi thao tác với các dữ liệu có thể thay đổi và cần phải giữ lại khi xoay màn hình, vì toàn bộ Activity sẽ được dựng lại từ “trang giấy trắng”. Còn với Flutter, như tôi đã nói, nó chạy trên bộ engine của nó, và bộ engine này không cần phải cấu hình giữ dữ liệu bằng tay.

Trên iOS (dù vẫn được trên Android), bạn có tùy chọn sử dụng các Widgets theo phong cách chính thống của iOSCupertinoStyled*, nhưng tốt nhất, bạn nên sử dụng theme Material, trừ khi bạn chỉ code cho iOS và muốn ứng dụng có cảm giác native hơn. Bởi Google mong muốn “phổ biến hóa”, “bành trướng hóa” giao diện Material trên nền tảng của đối thủ kiêm đối tác, nên Material widgets sẽ được quan tâm hơn, và bản thân Material widgets cũng phong phú, cung cấp nhiều tính năng mà giao diện Cupertino hay iOS gốc không có. Ngoài ra thì dân Android không thích ứng dụng có giao diện thuần iOS.

Sang bài tiếp theo, chúng ta sẽ bắt đầu bước vào việc dựng ứng dụng với Flutter. Tôi sẽ đi vào hai phần: Thay đổi giao diện, và thao tác gửi nhận dữ liệu từ mạng, để bạn có thể dựng ngay một ứng dụng Flutter đơn giản. Đối với những lĩnh vực khác, tôi sẽ trình bày dưới dạng các bài chia sẻ kinh nghiệm như các bài hướng dẫn về Android hay Web mà bạn thường thấy trên EITGUIDE.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.