Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Lập trình Kotlin Reactive cho màn hình đăng ký Android

by
Difficulty:IntermediateLength:LongLanguages:

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

RxJava 2.0 là một thư viện lập trình reactive phổ biến, đã giúp vô số nhà phát triển Android tạo ra các ứng dụng có độ phản ứng cao, sử dụng ít code hơn và ít phức tạp hơn, đặc biệt là khi quản lý nhiều thread (luồng).

Nếu bạn là một trong số nhiều nhà phát triển đã tiến hành chuyển đổi sang Kotlin, thì điều đó không có nghĩa là bạn cần phải từ bỏ RxJava!

Trong phần đầu tiên của loạt bài này, tôi đã chỉ cho bạn cách chuyển từ lập trình với RxJava 2.0 trong Java sang lập trình với RxJava trong Kotlin. Chúng tôi cũng đã xem xét cách loại bỏ boilerplate khỏi các dự án của bạn bằng cách tận dụng các chức năng mở rộng của RxKotlin, và bí quyết để tránh sự cố của chuyển đổi SAM mà nhiều nhà phát triển gặp phải khi lần đầu tiên bắt đầu sử dụng RxJava 2.0 với Kotlin.

Trong phần thứ hai này, chúng tôi sẽ tập trung vào cách RxJava có thể giúp giải quyết các vấn đề mà bạn gặp phải trong các dự án Android ngoài đời thực, bằng cách tạo một ứng dụng Android reactive bằng RxJava 2.0, RxAndroid và RxBinding.

Làm cách nào tôi có thể sử dụng RxJava trong các dự án thực tê?

Trong bài viết Reactive Programming with RxJava và RxKotlin, chúng tôi đã tạo ra một Observables và Observers đơn giản để in dữ liệu lên Android Studio Log Logcat nhưng đây không phải là cách bạn sử dụng RxJava trong thế giới thực.

Trong bài viết này, tôi sẽ chỉ cho bạn cách sử dụng RxJava để tạo ra một màn hình được sử dụng trong vô số ứng dụng Android: màn hình Sign Up điển hình.

A typical Sign Up screen that youll find in countless Android applications

Nếu ứng dụng của bạn có bất kỳ loại trải nghiệm đăng ký nào, thì ứng dụng đó thường có các quy tắc nghiêm ngặt về loại thông tin mà nó chấp nhận. Ví dụ: có thể mật khẩu cần vượt quá một số ký tự nhất định hoặc địa chỉ email phải ở định dạng hợp lệ.

Mặc dù bạn có thể kiểm tra dữ liệu vào từ người dùng khi họ nhấn nút Sign Up, nhưng đây không phải là trải nghiệm người dùng tốt nhất, vì nó dẫn họ đến việc gửi thông tin mà rõ ràng không bao giờ được ứng dụng của bạn chấp nhận.

Điều tốt hơn nhiều là theo dõi người dùng khi họ gõ phím, và sau đó cho họ thấy thông báo trước ngay khi họ nhập thông tin không đáp ứng yêu cầu ứng dụng của bạn. Bằng cách cung cấp kiểu phản hồi trực tiếp và liên tục này, bạn cung cấp cho người dùng cơ hội sửa chữa lỗi của mình trước khi nhấn nút Sign Up đó.

Mặc dù bạn có thể giám sát hoạt động của người dùng bằng Kotlin nguyên bản, chúng tôi có thể cung cấp chức năng này với ít code hơn bằng sự giúp đỡ của RxJava, cùng với một vài thư viện liên quan khác.

Tạo giao diện người dùng

Hãy bắt đầu bằng cách xây dựng giao diện người dùng. Chúng tôi sẽ thêm vào nội dung sau:

  • Hai EditTexts, nơi người dùng có thể nhập địa chỉ email của họ (enterEmail) và mật khẩu (enterPassword).
  • Hai TextInputLayout sẽ bao quanh hai EditTexts là enterEmail và enterPassword của chúng tôi. Các wrapper này sẽ hiển thị cảnh báo bất cứ khi nào người dùng nhập địa chỉ email hoặc mật khẩu không đáp ứng yêu cầu ứng dụng của chúng tôi.
  • Nút hiển thị mật khẩu, cho phép người dùng chuyển đổi giữa việc ẩn đi mật khẩu và xem nó dưới dạng văn bản đơn giản.
  • Một nút Sign Up. Để giữ cho ví dụ này tập trung vào RxJava, tôi sẽ không triển khai phần này của trải nghiệm đăng ký, vì vậy tôi sẽ đánh dấu nút này là disabled (vô hiệu).

Đây là bố trí hoàn chỉnh của tôi:

Bạn có thể copy/paste chúng vào ứng dụng của mình nếu muốn hoặc bạn có thể tải xuống code nguồn dự án từ repo GitHub của chúng tôi.

Xây dựng trải nghiệm đăng nhập reactive với Kotlin

Bây giờ, hãy cùng xem xét cách chúng ta có thể sử dụng RxJava, cộng với một vài thư viện liên quan, để theo dõi dữ liệu nhập của người dùng và cung cấp phản hồi trong thời gian thực.

Tôi sẽ giải quyết màn hình Sign Up trong hai phần. Trong phần đầu tiên, tôi sẽ chỉ cho bạn cách sử dụng thư viện RxBinding để đăng ký và trả lời các sự kiện thay đổi văn bản. Trong phần thứ hai, chúng tôi sẽ tạo một số hàm chuyển đổi xác thực dữ liệu nhập của người dùng, sau đó hiển thị thông báo lỗi khi thích hợp.

Tạo một dự án mới với các thiết lập từ bạn, nhưng khi được yêu cầu thì hãy đảm bảo bạn chọn hộp Inlcude Kotlin Support.

Phản hồi với các sự kiện thay đổi văn bản

Trong phần này, chúng tôi sẽ thực hiện các chức năng sau:

  • Phát hiện khi người dùng đang gõ vào trường enterEmail.
  • Bỏ qua tất cả các sự kiện thay đổi văn bản xảy ra trong một khoảng thời gian ngắn, vì điều này cho thấy rằng người dùng vẫn đang gõ.
  • Thực hiện một hành động khi người dùng dừng việc gõ phím. Trong ứng dụng đã hoàn thành của chúng tôi, đó là nơi chúng tôi sẽ xác thực dữ liệu nhập của người dùng, nhưng trong phần này, tôi sẽ chỉ hiển thị một Toast.

1. RxBinding

RxBinding là một thư viện giúp dễ dàng chuyển đổi một loạt các sự kiện UI thành Observables, tại thời điểm đó bạn có thể xem chúng như bất kỳ luồng dữ liệu RxJava nào khác.

Ví dụ, chúng tôi sẽ theo dõi các sự kiện thay đổi văn bản, bằng cách kết hợp widget.RxTextView của RxBinding với phương thức afterTextChangeEvents, ví dụ:

Vấn đề với việc xử lý các sự kiện thay đổi văn bản dưới dạng luồng dữ liệu là ban đầu cả enterEmail và enterPassword đều trống và chúng tôi không muốn ứng dụng của mình phản ứng với trạng thái trống này dù cho nó là dữ liệu đầu tiên phát tán trong luồng. RxBinding giải quyết vấn đề này bằng cách cung cấp phương thức skipInitialValue() mà chúng tôi sẽ sử dụng để hướng dẫn mỗi Observer bỏ qua giá trị ban đầu của luồng.

Tôi nói về thư viện RxBinding chi tiết hơn trong bài viết RxJava 2 for Android Apps của tôi.

2. Toán tử RxJava .debounce()

Để cung cấp trải nghiệm người dùng tốt nhất, chúng tôi cần hiển thị bất kỳ cảnh báo mật khẩu hoặc email nào có liên quan sau khi người dùng nhập hoàn tất, và trước khi họ nhấn nút Sign Up.

Nếu không có RxJava, việc xác định khoản thời gian eo hẹp này thường yêu cầu chúng ta triển khai một Timer, nhưng trong RxJava, chúng ta chỉ cần áp dụng toán tử debounce() cho luồng dữ liệu của mình.

Tôi sẽ sử dụng toán tử debounce() để lọc tất cả các sự kiện thay đổi văn bản xảy ra liên tiếp, tức là khi người dùng vẫn đang gõ phím. Ở đây, chúng tôi đã bỏ qua tất cả các sự kiện thay đổi văn bản xảy ra trong cùng một cửa sổ kéo dài 400 mili giây:

3. AndroidSchedulers.mainThread() của RxAndroid

AndroidSchedulers.mainThread từ thư viện RxAndroid giúp chúng ta dễ dàng chuyển sang luồng UI chính quan trọng nhất của Android.

Vì nó chỉ có thể cập nhật giao diện người dùng Android từ luồng UI chính chính, chúng tôi cần đảm bảo rằng chúng tôi đã xử lý luồng này trước khi chúng tôi cố gắng hiển thị bất kỳ cảnh báo email hoặc mật khẩu nào và trước khi chúng tôi hiển thị Toast của chúng tôi.

4. Subscribe (đăng ký)

Để nhận dữ liệu được phát ra từ enterEmail, chúng tôi cần đăng ký nó:

5. Hiển thị toast

Sau cùng, chúng tôi muốn ứng dụng của mình phản hồi các sự kiện thay đổi văn bản bằng cách xác thực dữ liệu nhập của người dùng, nhưng để mọi thứ đơn giản hơn, tại thời điểm này, tôi chỉ đơn giản là sẽ hiển thị một Toast.

Code của bạn sẽ trông giống như thế này:

6. Cập nhật các phụ thuộc của bạn

Vì chúng tôi sử dụng một vài thư viện khác nhau, chúng tôi cần mở file dự án build.gradle của dự án và bổ sung RxJava, RxBinding và RxAndroid làm các phụ thuộc cho dự án:

Bạn có thể kiểm tra phần này của dự án bằng cách cài đặt nó trên thiết bị vật lý như điện thoại thông minh hoặc máy tính bảng Android hoặc Android Virtual Device (AVD). Chọn enterEmail EditText và bắt đầu nhập; một Toast sẽ xuất hiện khi bạn ngừng gõ.

Test your projects enterEmail EditText

Xác thực dữ liệu nhập từ người dùng với các hàm chuyển đổi

Tiếp theo, chúng tôi cần đưa ra một số quy tắc cơ bản về loại dữ liệu nhập mà ứng dụng của chúng tôi sẽ chấp nhận, sau đó kiểm tra dữ liệu nhập của người dùng theo tiêu chí này và hiển thị thông báo lỗi khi thích hợp.

Kiểm tra email hoặc mật khẩu của người dùng là một quá trình gồm nhiều bước, vì vậy để giúp code của chúng ta dễ đọc hơn, tôi sẽ tổng hợp tất cả các bước này vào hàm chuyển đổi của riêng chúng.

Đây là khởi điểm của hàm chuyển đổi validateEmail:

Trong đoạn code trên, chúng tôi sử dụng toán tử filter() để lọc kết quả xuất ra của Observable dựa trên việc nó có khớp với pattern Patterns.EMAIL_ADDRESS hay không.

Trong phần tiếp theo của hàm chuyển đổi, chúng ta cần xác định điều gì sẽ xảy ra nếu dữ liệu nhập không khớp với patter EMAIL_ADDRESS. Theo mặc định, mọi lỗi không thể phục hồi sẽ kích hoạt gọi tới onError(), hàm này sẽ kết thúc luồng dữ liệu. Thay vì kết thúc luồng, chúng tôi muốn ứng dụng của chúng tôi hiển thị thông báo lỗi, vì vậy tôi sẽ sử dụng onErrorResumeNext, nó hướng dẫn Observable phản hồi lỗi bằng cách chuyển quyền kiểm soát sang một Observable mới, thay vì gọi onError(). Điều này cho phép chúng tôi hiển thị thông báo lỗi tùy chỉnh của chúng tôi.

Bước cuối cùng là áp dụng hàm chuyển đổi này cho luồng dữ liệu email, sử dụng toán tử .compose(). Tại thời điểm này, MainActivity.kt của bạn sẽ trông giống như thế này:

Cài đặt dự án này trên thiết bị Android hoặc AVD của bạn và bạn sẽ thấy rằng phần email của màn hình Sign Up hiện đang kiểm tra dữ liệu nhập của bạn thành công. Hãy thử nhập bất cứ gì ngoài địa chỉ email và ứng dụng sẽ cảnh báo bạn rằng đây không phải là một dữ liệu hợp lệ.

Enter anything other than a valid email address and the app will display a warning message

Hãy lặp lại quá trình: Kiểm tra mật khẩu người dùng

Tại thời điểm này, chúng tôi có một trường enterEmail đang hoạt động và việc triển khai enterPassword chủ yếu chỉ là lặp lại các bước tương tự.

Trong thực tế, sự khác biệt lớn duy nhất là hàm chuyển đổi validatePassword của chúng tôi cần kiểm tra các tiêu chí khác nhau. Tôi sẽ chỉ định rằng dữ liệu nhập mật khẩu của người dùng phải dài ít nhất 7 ký tự:

Sau khi lặp lại tất cả các bước trước đó, MainActivity.kt đã hoàn thành sẽ trông giống như thế này:

Cài đặt dự án này trên thiết bị Android hoặc AVD của bạn và thử nghiệm nhập vào các trường enterEmail và enterPassword. Nếu bạn nhập một giá trị không đáp ứng các yêu cầu của ứng dụng, thì nó sẽ hiển thị thông báo cảnh báo tương ứng mà không cần phải nhấn nút Sign Up.

Bạn có thể tải xuống dự án hoàn chỉnh này từ GitHub.

Tổng kết

Trong bài viết này, chúng tôi đã xem xét cách RxJava có thể giúp giải quyết các vấn đề trong thế giới thực mà bạn sẽ gặp phải khi phát triển các ứng dụng Android của riêng mình, bằng cách sử dụng RxJava 2.0, RxBinding và RxAndroid để tạo màn hình Sign Up.

Để biết thêm thông tin cơ bản về thư viện RxJava, hãy nhớ xem bài viết Get Started With RxJava 2.0 của chúng tôi.

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.