Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Mobile Development
Code

Xây dựng ứng dụng đầu tiên của bạn với Fuse

by
Difficulty:BeginnerLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)

Bạn đã học các khái niệm cơ bản về Fuse, giờ là lúc bạn thực hành và xây dựng một ứng dụng. Trong hướng dẫn này, bạn sẽ học các phát triển một ứng dụng bằng framework Fuse. Cụ thể bạn sẽ học những phần sau đây:

  • Cách code bằng UX Markup.
  • Cách sử dụng Observable, Timer và Geolocation API.
  • Cách xem trước một ứng dụng bằng desktop preview và custom preview.

Nếu bạn cần làm quen với Fuse, hãy xem qua bài viết trước trong loạt bài: Introducing Fuse for Cross Platform App Development.

Các điều kiện tiên quyết

Để bắt đầu với Fuse, đến trang downloads và đăng ký một tài khoản. Bạn cũng có thể đăng nhập vào một tài khoản bạn đã có sẵn.

Fuse hỗ trợ cả Windows vả MacOS. Tải về cài đặt đúng bộ cài đặt cho hệ điều hành của bạn. Trong trang downloads, họ cũng cung cấp những plugin cho Fuse phù hợp với nhiều trình biên tập khác nhau. Cài đặt một trình biên tập. Các plugin gồm có code completion (tự hoàn thành code), goto definition (đến định nghĩa hàm), và các log (nhật ký) được tạo ra từ ứng dụng, tất cả làm cho việc phát triển app trở nên thuận tiện hơn.

Chúng ta sẽ đề cập cách xem trước ứng dụng bằng custom preview. Việc này cần có Android Studio và Xcode đã cài đặt trên máy tính của bạn.

Các hiểu biết cơ bản về những công nghệ web như HTML, CSS và JavaScript rất hữu ích, nhưng không bắt buộc.

Kết quả bạn sẽ tạo ra

Bạn sẽ tạo ra một ứng dụng stopwatch, cũng dùng đo khoảng cách. Khoảng cách được đo bằng geolocation (vị trí địa lý). Người dùng có thể tạo ra những vòng, và từng khoảng cách riêng lẻ và thời gian cho mỗi vòng sẽ hiện thị trên màn hình.

Đây là diện mạo của ứng dụng:

Final Output HIIT Stopwatch

Bạn có thể xem toàn bộ mã nguồn trên Github repo của bài viết.

Tạo một dự án Fuse mới

Một khi bạn cài Fuse Studio xong, bạn có thể tạo một dự án Fuse mới. Chỉ cần mở Fuse Studio và nhấp vào nút New Fuse Project. Nhập vào tên dự án và nhấn Create.

Create a new Fuse project

Thao tác này sẽ tạo một thư mục mới trong thư mục đang chọn. Mở thư mục đó và mở file MainView.ux. Mặc định chỉ có thẻ <App>. Cập nhật thêm thẻ <Text>  và sau đó lưu file:

Preview sẽ được cập nhật với text bạn đã nhập vào:

Hello world output

Đó là quy trình phát triển chính trong Fuse. Chỉ cần lưu thay đổi đến bất file nào trong thư mục của dự án, và chúng tự động được hiển thị trên desktop preview.

Bạn cũng có thể xem log ở dưới cùng của panel. Bạn có thể tự kích hoạt bằng console.log(), giống như trong trình duyệt. Khác biệt duy nhất là bạn phải JSON.stringify() các đối tượng để thấy giá trị của chúng, khi triển khai console.log() với Fuse chỉ có thể xuất ra chuỗi.

UX Markup

Giờ chúng ta sẵn sàng để xây dựng ứng dụng. Mở file MainView.ux và xoá thành phần <Text>  trước đó. Theo cách đó, chúng ta có thể bắt đầu từ đầu:

Thêm phông chữ

Giống như một tài liệu HTML, tiêu chuẩn cần bao gồm các tài nguyên nhưng font, stylesheet (kiểu cho tài liệu) và các mã lệnh trước phần markup thực sự của trang. Vậy hãy bổ sung nhưng phần sau vào thành phần :

Font cụ thể sẽ được import vào thuộc tính File và đặt tên là Thin. Lưu ý rằng nó không được đặt làm font mặc định cho cả trang. Nếu bạn muốn dùng Font này, bạn phải dùng tên của nó (Thin) trong text cụ thể mà bạn muốn áp dụng.

Bạn có thể tải font từ Github repo của bài viết. Sau đó, tạo một thư mục assets/fonts/robot bên trong thư mục gốc và đặt file .ttf vào đó.

Nếu bạn muốn sử dụng một font khác, bạn có thể tải nó từ dafont.com. Đó là nơi tôi tải font cho ứng dụng này.

Tiếp theo, chúng tôi muốn dùng icon ở trong ứng dụng. Fuse không có những thành phần và những bộ icon dựng sẵn cho phép bạn thực hiện điều này. Fuse cho phép bạn kèm một font icon đang có trong ứng dụng của bạn. Khi font icon là font chủ đạo, chúng ta có thể dùng cùng một phương pháp để kèm các font:

Bạn có thể tải icon font từ Github repo hoặc tải trực tiếp từ fontawesome.com. Lưu ý rằng không phải tất cả icon trên fontawesome đều miễn phí, vì thế tốt nhất là kiểm tra trang icon thực tế trước khi sử dụng. Nếu bạn thấy nhãn "pro" kế bên icon, vậy bạn không thể dùng nó trong dự án mà không trả tiền.

Đính kèm JavaScript

Tiếp theo, chúng ta cần kèm file JavaScript cho trang này. Chúng ta có thể thực hiện điều này bằng thành phần <JavaScript>:

Đừng quên tạo file scripts/MainView.js ở thư mục gốc của dự án:

Tạo các component mới

Để tối đa việc sử dụng code, Fuse cho phép tạo những component mới từ những component đang có. Trong code bên dưới, ta dùng <Panel> để tạo một button mới. Hãy xem như một div đóng vai trò là container cho những thành phần khác. Trong trường hợp này, chúng ta dùng nó như một component có thể tái sử dụng để tạo một button.

Fuse có nhiều thành phần. Có những thành phần để bố trí nội dung như <Panel> , các thành phần để hiển thị các điều khiển của người dùng, các trang và điều hướng, mã lệnh và dữ liệu, và những phần cơ bản để xây dựng UI. Mỗi thành phần có một bộ thuộc tính riêng, cho phép bạn thay đổi dữ liệu, phần trình bày, và hành vi.

Để tạo một component có thể tái sử dụng, bổ sung một thuộc tính ux:Class vào một thành phần hiển thị bạn muốn sử dụng làm cơ sở. Trong trường hợp này, chúng ta đang dùng <Panel>  là cơ sở. Bạn có thể bổ sung kiểu mặc định sau đó. Việc này tương tự như cách tạo kiểu được thực hiện trong CSS. Margin bổ sung thêm khoảng trống bên ngoài container. Ở đây ta chỉ xác định một giá trị riêng lẻ, vì thế margin này được áp dụng trên tất cả các phía của panel. Color thêm một màu nền vào thành phần:

Bên trong <Panel>, chúng tôi muốn hiển thị text của button. Ta muốn biến nó thành một component có thể tái sử dụng, vì thế chúng ta cần một phương pháp để chuyển các thuộc tính khi chúng ta cần dùng component này sau đó. Việc này cho phép chúng tôi đạt những kết quả khác nhau chỉ bằng cách thay đổi các thuộc tính.

Trong <Panel>, sử dụng loại dữ liệu của giá trị bạn muốn truyền vào như tên của thành phần, và sau đó bổ sung tên của thuộc tính qua ux:Property. Bạn có thể hiện giá trị được cung cấp cho thuộc tính bằng {ReadProperty PropertyName}, với PropertyName là giá trị bạn cung cấp cho ux:Property. Điều này sẽ cho phép bạn cung cấp thuộc tính Text bất cứ lúc nào bạn đang sử dụng component .

Tiếp theo, chúng tôi muốn đề xuất cho người dùng một số kiểu phản hồi trong khi button đang được nhấn. Chúng tôi có thể thực hiện điều đó thông qua triggersanimators. Trigger cơ bản là event listiner (trình lắng nghe sự kiện) - trong trường hợp này là <WhilePressed>. Và animators là các diễn hoạt hoặc hiệu ứng bạn muốn thực hiện trong khi trigger hoạt động. Code bên dưới sẽ làm button to hơn 10% so với kích thước nguyên bản và thay đổi màu sắc của nó. DurationDurationBack cho phép bạn xác định sẽ mất bao lâu để hoạt hình hoàn tất.

Tiếp theo, ta tạo component <IconBtn>. Như tên gọi đề xuất, đây là button chỉ hiển thị một icon với nội dung của nó. Điều này giống như component trước đó, dù có vài thứ mởi mẻ chúng ta từng thực hiện.

Đầu tiên là thuộc tính Ux:Name. Thuộc tính này cho phép chúng ta đặt tên cho một thành phần cụ thể để chúng ta có thể tham chiếu sau đó. Trong tình huống này, ta đang dùng nó để đổi thuộc tính Color trong lúc button đang được nhấn.

Chúng ta cũng sử dụng mệnh đề điều kiện gọi là <WhileTrue> cho phép chúng ta vô hiệu trigger <WhilePressed> khi giá trị cho is_running là sai. Ta sẽ cung cấp giá trị cho biến này khi chúng ta gặp phần JavaScript. Lúc này, hãy biết rằng biến số này cho biết khi nào timer đang chạy hoặc không chạy.

Nội dung chính

Bây giờ ta có thể tiếp tục với phần nội dung chính. Đầu tiên, chúng ta đưa tất cả vào <StackPanel>. Như tên đề xuất, nó sẽ cho phép chúng ta "stack" (sắp xếp) các con của nó theo chiều dọc hoặc chiều ngang. Mặc định, nó theo hướng nằm đứng nên ta không cần xác định rõ ràng:

Trong code bên trên, ta dùng 4 giá trị của Margin. Không như CSS, giá trị là left (trái), top (trên cùng), right (phải) và bottom (dưới). Nếu chỉ xác định 2 giá trị, thì là left-right, top-bottom. Bạn có thể dùng công cụ lựa chọn trong Fuse Studio để trực quan hoá margin đang được áp dụng.

Kế đến, ta sẽ thêm một hình nền vào trang. Một đường dẫn file cho phép bạn đưa hình ảnh nền bạn muốn dùng. StretchMode của Fill làm hình nền trải rộng toàn kích thước màn hình.

Bạn có thể tải về hình ảnh nền tôi đã dùng từ Github repo của bài viết. Hoặc bạn có thể tìm những hình mẫu tương tự trên website của Toptal.

Kế tiếp, hiện tên của ứng dụng. Bên dưới là trường text time-elapsed (thời gian đã trôi qua). Text này cần được cập nhật thường xuyên, vì thế chúng ta cần đưa nó vào một biến số có thể cập nhật bằng JavaScript. Để hiển thị vài text được tạo ra từ file JavaScript của trang này, thì bạn cần bao bọc tên biến trong dấu ngoặc nhọn. Sau đó, bạn sẽ thấy gía trị của biến số này được cung cấp từ file JavaScript như thề nào:

Tiếp đến, chúng ta dùng component đã tạo ra trước đó. Trong Fuse, bạn phải dùng Unicode đã được gán cho icon font bạn muốn sử dụng. Bạn cũng cần dùng &#x làm tiền tố. Khi nút này được nhấn (gọi là Clicked), hàm addLap() được khai báo trong JavaScript được xử lý:

Trong Font Awesome, bạn có thể tìm unicode của font icon trên trang của nó.

Ngay bên dưới button để tạo một vòng mới là vài text mô tả rằng button ở trên dùng để tạo thêm vòng mới.

Kế tiếp, hiển thị button để bắt đầu và két thúc timer. Việc này sẽ xử lý một hàm được khai báo sau đó:

Tiếp theo, chúng ta cần hiển thị những lap do người dùng thêm vào. Gồm có số lap, khoảng cách được nhắc đến, và thời gian đã sử dụng. Thành phần <Each> cho phép chúng ta lặp qua một tập hợp những đối tượng và hiển thị những thuộc tính cho từng đối tượng.

Trong code bên trên, ta dùng <DockPanel> để bao bọc nội dụng cho mục. Loại panel này giúp chúng ta "dock" những mục con trên các phía khác nhau (top, left, right và bottom) của những không gian đang có. Mặc định, nó định vị những mục con trực tiếp nằm trên cùng của từng mục. Để dàn đều những mục này, bạn cần bổ sung thuộc tính Alignment.

Mã JavaScript

Giờ ta đã sẵn sàng để bổ sung mã JavaScript. Trong Fuse, JavaScript được sử dụng chủ yếu cho business logic và hoạt động với các chức năng nguyên bản của thiết bị. Các hiệu ứng, chuyển đổi và hoạt hình để tương tác với UI đã được xử lý bởi UX Markup.

Bắt đầu bằng cách import tất cả API chúng ta cần dùng. Bao gồm cả Observable, được sử dụng chính cho việc gán biến vào UI. Những biến số này có thể được cập nhật bằng JavaScript. Timer tương đương với hàm setTimeoutsetInterval trong phiên bản web của JavaScript. Geolocation cho chúng ta biết vị trí hiện tại của người dùng.

Tiếp theo, chúng ta khởi tạo tất cả các biến observable mà chúng ta sẽ dùng. Đó là những biến số mà bạn đã thấy trong UX markup trước đó. Giá trị của những biến này được cập nhật xuyên suốt lúc sử dụng ứng dụng, vì thế chúng ta biến chúng thành các biến observable. Việc này cho phép ta cập nhật nội dung của UI hiệu quả khi những giá trị này thay đổi.

Sau đó, chúng ta có thể xét giá trị ban đầu cho nút thay đổi trạng thái và text của timer:

Đó là cách bạn thay đổi giá trị của biến observable. Khi những biến này không nằm bên trong bất kỳ hàm nào, nó sẽ cập nhật UI ngay tức thì khi ứng dụng khởi động.

Thiết lập giá trị ban đầu cho timer, lap time và vị trí cho mỗi lap:

Hàm toggle() được dùng để khởi động và dừng timer. Khi timer đang dừng và người dùng nhấn vào nút toggle, đó là lần duy nhất chúng ta khởi tạo lại giá trị cho timer và những lap. Đó là vì chúng ta muốn người dùng thấy những giá trị này thậm chí sau khi họ đã dừng timer.

Sau đó, lấy thông tin vị trí hiện tại của người dùng và đưa vào mảng locations. Điều này cho phép ta so sánh vị trí đó với những địa điểm kế tiếp, một khi người dùng thêm vào một lap. Sau đó tạo một timer để xử lý mỗi 10 mili giây. Chúng ta gia tăng time tổng thể và lap_time cho mỗi lần xử lý. Sau đó cập nhật UI với giá trị đã định dạng bằng hàm formatTimer():

Khi người dùng dừng timer, chúng ta xoá nó bằng phương thức delete() trong timer. Việc này yêu cầu timer_id được trả về khi timer được tạo ra.

Tiếp đến là hàm để định dạng timer. Hàm này chuyển đổi mili giây sang giây và sang phút. Chúng ta đã biết hàm này được chạy mỗi 10 mili giây. Và time được tăng lên 1 sau mỗi lần hàm này xử lý. Vi vậy để lấy số mili giây, chúng ta chỉ cần nhân time với 10. Từ đó, chúng ta sẽ tính ra giây và phút dựa trên giá trị tương đương của đơn vị đo.

Mỗi lần user chạm nút refresh, hàm addLap() xử lý. Điều này thêm vào một giá trị phía trên của laps:

Đây là hàm để lấy khoảng cách đo bằng mét. Nó sử dụng công thức Haversine:

Đừng quên xuất tất cả giá trị observable:

Geolocation Package

Để cho nhẹ dung lượng, Fuse không thực sự kèm tất cả các gói mà nó hỗ trợ mặc định. Các thông báo cục bộ và geolocation, bạn cần cho Fuse biết để kèm theo chúng khi dựng ứng dụng. Mở StopWatch.unoproj ở thư mục gốc của dự án và kèm theo Fuse.GeoLocation bên dưới mảng Packages:

Điều này sẽ hướng dẫn Fuse đính kèm gói GeoLocation bất cứ khi nào xây dựng ứng dụng để xem trước hoặc tạo mội trình cài đặt.

Thiết lập Preview tuỳ chọn

Trước khi bạn chạy ứng dụng trên thiết bị iOS, trước tiên bạn cần bổ sung bundle identifier vào ứng dụng. Mở file StopWatch.unoproj và thêm dòng sau vào bên dưới iOS. Đây sẽ là định danh duy nhất cho ứng dụng khi được đưa lên App Store:

Kế đến trên Xcode, đăng nhập với tài khoản Apple Developer. Nếu bạn chưa có, bạn có thể tới website của Apple Developer và tạo một tài khoản. Thực sự miễn phí để phát triển và kiểm thử các ứng dụng trên thiết bị iOS. Tuy nhiên, có vài hạn chế nếu bạn không nằm trong chương trình cho người phát triển.

Khi tài khoản của bạn được tạo ra, đến phần thiết lập preferences của Xcode vào thêm vào tải khoảng Apple của bạn. Sau đó nhấp Manage Certificates và bổ sung một chứng chỉ mới cho phần phát triển iOS. Chứng chỉ này được dùng để bảo đảm rằng ứng dụng từ một nguồn có danh tính.

Khi việc này hoàn thành, bạn sẽ có thể chạy ứng dụng trên thiết bị của bạn. Nhấn vào Preview > Preview on iOS trong Fuse Studio và chờ Xcode được khởi chạy. Một khi Xcode mở ra, chọn thiết bị của bạn và nhấp vào nút play. Điều này sẽ xây dựng úng dụng và cài đặt nó lên thiết bị của bạn. Nếu có lỗi khi dựng ứng dụng, thì hầu hết có thể là bundle identifier không phải là duy nhất:

change the bundle ID

Thay đổi Bundle Identifier thành thứ gì đó duy nhất sẽ giải quyết được vấn đề này. Một khi lỗi ở bên dưới mục đăng nhập biến mất, nhấp vào nút Play lần nữa để xây dựng lại ứng dụng. Thao tác này sẽ cài đặt ứng dụng trên thiết bị của bạn.

Tuy nhiên bạn sẽ không thể mở ứng dụng trừ khi bạn phê duyệt nó. Bạn có thể làm điều đó trên thiết bị iOS bằng cách đến Settings > General > Device Management và chọn email tương ứng với tài khoảng Apple Developer. Xác thực nó, và ứng dụng của sẽ được thông qua.

Với Android, bạn sẽ có thể xem trước ứng dụng mà không cần thêm các bước nào khác.

Kết luận

Thế đấy! Trong bài hướng dẫn này, bạn đã học cơ bản của việc tạo một ứng dụng bằng framework Fuse. Cụ thể, bạn đã tạo một ứng dụng stopwatch. Bằng việc tạo ứng dụng này, bạn đã học cách làm việc cùng UX Markup của Fuse và một vài JavaScript API của Fuse. Bạn cũng đã học cách sử dụng Fuse Studio để xem trước ứng dụng trên máy tính và điện thoại của bạn khi đang phát triển ứng dụng.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.