Android

Sử dụng Android VectorDrawable

Nếu bạn bắt đầu học code Android từ năm 2015 là bạn đã quen thuộc với VectorDrawable, trong khi những bạn học trước đó mà lại có ít thời gian để trau dồi, nâng cao kiến thức thì có lẽ cũng chưa sử dụng rộng rãi VectorDrawable, và đó sẽ là một thiếu sót khá quan trọng. Vì vậy, EITGUIDE sẽ gửi tới các bạn hai bài viết về VectorDrawable và VectorDrawableCompat để bạn có thể nắm rõ và chuyển hẳn sang dùng VectorDrawable để tận dụng tất cả những điểm mạnh của nó.

1. Sự ra đời của VectorDrawable

Trước đây, khi bạn gán src cho một ImageView hay icon của ActionBar optionsMenu, bạn phải dùng ảnh định dạng PNG (thông thường là có độ trong suốt alpha). Điều này sẽ dẫn tới hai vấn đề. Một là do Android có độ phân mảnh rất cao về kích thước và độ phân giải màn hình là muôn hình vạn trạng, vì vậy bạn phải làm không ít các bản sao của cùng một icon cho các kích thước màn hình khác nhau theo chỉ số DPI (tức ldpi, mdpi, hdpi, xhdpi, xxhdpi). Điều này sẽ dẫn tới kích thước tập tin APK sẽ tăng lên cũng như bạn phải tốn khá nhiều công sức. 1 icon hay 10 icons thì không sao, nhưng 100 cái thì sẽ gây không ít khó khăn cho nhà phát triển. Tệ hơn nữa là nếu bạn thiết kế lại một icon thì phải export và cóp pát lại vào từng thư mục drawable một và dễ gây ức chế lắm. Vấn đề thứ hai là ảnh PNG, cũng như WEBP là định dạng ảnh tĩnh. Vì vậy, bạn sẽ gặp hạn chế khi thực hiện “biến hình” trên một đối tượng trong ảnh. Để bạn dễ hình dung hơn thì xin mời bạn xem ảnh bên dưới:

pause-resume-vector-drawable

Vâng, tôi biết là bạn đang nghĩ tới GIF. Tuy nhiên, việc hỗ trợ GIF trong android:src hoặc android:icon của ImageView khá hạn chế, có ảnh chạy tốt, có ảnh lại không chạy chính xác cũng như có cái khác lại không thèm chạy, cũng như việc bạn phải làm đi làm lại nhiều bản sao cho nhiều loại màn hình. Do vậy, trước sự phát triển mạnh mẽ của xu hướng UX bắt mắt để thu hút người dùng, các ảnh tĩnh có vẻ khá “hụt hơi”. Vì vậy, cùng với Android 5.0 Lollipop, tại IO 2014, Google đã giới thiệu VectorDrawable.

2. VectorDrawable là gì?

Là một nhà thiết kế biểu tượng, vẽ graphics, tôi nghĩ là bạn đã có những kiến thức về các paths khi thiết kế các đối tượng bằng Inkscape hay Adobe Illustrator và Photoshop. Thực chất các tập tin SVG hoặc PSD chứa các đối tượng dưới dạng các paths với tọa độ và phương trình biểu diễn, để khi bạn mở chúng với Inkscape hoặc Ai hoặc Ps thì nhiệm vụ của phần mềm là dựng các đối tượng từ các paths được lưu. Chẳng hạn, đây là nội dung của một tập tin SVG được mở với một Text Editor bình thường:

Với mục đích sử dụng hướng render này vào Android, VectorDrawable đã ra đời. Như vậy, các đối tượng sẽ được định nghĩa dưới dạng các paths và khi Android system đọc tới tập tin này thì nó sẽ tiến hành vẽ đối tượng theo các paths đã định. Nếu bạn vẫn còn cảm thấy khó hiểu, thì bạn hãy nghĩ là mình đang muốn cái máy vẽ đồ thị theo các điểm đã cho trước. Nghe có vẻ không hay cho lắm vì GPU của máy sẽ phải tốn công dựng đối tượng ở runtime. Vậy, VectorDrawable có điểm gì hay mà hiện tại, những Android coder chuyên nghiệp đều thích dùng nó?

  • Một là, bạn chỉ cần một drawable duy nhất cho tất cả các kích thước dpi khác nhau. Đơn giản là GPU sẽ chỉ render theo paths có sẵn chứ không phải load ảnh tĩnh cũng như phải scale ảnh nhỏ thành ảnh lớn gây hiện tượng vỡ ảnh.
  • Hai là, bạn có thể “thao túng” (từ gốc là manipulate, cá nhân tôi hiện vẫn chưa tìm được từ tiếng Việt có nghĩa chính xác, nếu bạn tìm được xin vui lòng để lại bình luận) các thành phần của drawable. Ngoài các paths, bạn còn có thể thay đổi cả màu sắc nữa, và hơn nữa là bạn có thể truyền thằng tham số màu vào, nên sau này bạn muốn đổi màu mà vẫn giữ nguyên hình dạng của đối tượng, bạn chỉ thay đổi thuộc tính màu mà thôi, không cần thiết phải tạo tập tin mới.

Tuy nhiên, cũng như những thứ khác trên cõi trần thế này, VectorDrawable cũng có những khuyết điểm sau:

  • Một là, nó chỉ thích hợp cho các drawable đơn giản, vì nó không phải là một tập tin hình ảnh thuần về điểm ảnh như PNG hay WEBP, mà là tập tin chứa dữ liệu về paths để GPU render khi đọc tới nó, do đó việc dựng ảnh có thể mất thời gian và gây tỏa nhiệt cho hệ thống. Chẳng hạn bạn muốn render một tấm ảnh 20MP với các chi tiết người, cây cối, đồ vật – tức là biến một tấm ảnh chụp thành các đối tượng đồ họa – thì tốt nhất bạn dùng ảnh JPG giùm.
  • Hai là, bạn cũng cần biết tối ưu hóa các paths, nghĩa là với cùng một kết quả do mắt nhìn như nhau, bạn nên ưu tiên cách nào có các paths đơn giản hơn, trừ trường hợp bạn có ý tưởng sẽ tạo hiệu ứng với các paths. Điều này sẽ giảm tải bớt khối lượng cho GPU.
  • Ba là, vector drawable là một framework lib, và nó chỉ xuất hiện trên API 21 tức Android Lollipop 5.0 về sau. Vì vậy, nếu bạn vẫn đang sử dụng Android Studio thời kì “đồ đá”, phiên bản thấp hơn 2.1 mà build ứng dụng với minSdk là 14 thì ứng dụng sẽ bị “văng liên tục” trên Android 4.0 tới 4.4. Nhưng may mắn là Studio 2.1 đã có các cách tránh né với một số thư viện support đi kèm với appcompat-v7, khi cài đặt ứng dụng lên các phiên bản Android 2.3-4.4 thì các vector drawables sẽ được chuyển thành PNG trên phần dalvik cache. Ngoài ra thì chúng ta đã có bộ thư viện support ứng với bộ package của vector frawable là vector drawable compat, nên khuyết điểm thứ ba này chỉ còn giới hạn ở mỗi chỗ là VectorDrawable(Compat) chỉ có thể được render trong package runtime – tức là trong môi trường của app package mà thôi. Nếu bạn sử dụng vector drawable cho homescreen widgets trên Android 2.3-4.4 thì chúng sẽ “tạch”. Về việc sử dụng vector drawable compat, tôi sẽ nói trong bài viết tới.

Trước khi sang phần tiếp theo, tôi sẽ đưa ra phiên bản vector drawable của đối tượng svg bên trên. Bạn muốn biết nó là gì thì hãy chạy Android Studio lên, tạo project mới và cóp pát nó vào để preview:

3. Tạo Vector drawable

Nhiều bạn chưa thao tác với vector drawable, nhìn vào phần pathData sẽ thấy một mớ “hổ lốn” và không tài nào hiểu, chẳng hạn phần “M7.52” có nghĩa là gì. Không sao đâu, tôi cũng không hiểu nên bạn không có gì phải xoắn lên. Và thực tế, chúng ta cũng không có bài học nào về cách viết String trong pathData cả. “Đùa à? Vậy thì tôi muốn thiết kế và sử dụng một vector drawable của tôi thì làm cách nào?”.

Như tôi đã nó từ đầu bài, vector drawable có xuất thân từ SVG và PSD mà thôi. Do vậy bạn cứ thiết kế các đối tượng đồ họa dưới dạng SVG với Inkscape hoặc Adobe Illustrator, hoặc PSD với Adobe Photoshop rồi để Studio tự lo tiếp bằng cách import vào project. Bạn chọn File -> New -> Vector Assets. Trong cửa sổ được hiện ra, bạn chọn Asset Type là Local file (SVG, PSD) rồi nhấn vào nút 3 chấm ngang ở Path để trỏ tới và mở tập tin SVG hoặc PSD mà bạn đã tạo. Như tôi đã nói, Studio sẽ lo parse paths cho bạn, bạn không cần lo lắng gì thêm. Lưu ý rằng với Inkscape, bạn nên chọn lưu file ở dạng SVG bình thường thay cho Inkscape SVG, sẽ dễ để Studio import hơn.

VectorAssetPicker

Trước khi chia tay, tôi xin gửi bạn đường link để tải Inkscape là www.inkscape.org. Bạn đừng nghĩ nó đơn giản là sẽ “dở”. Chính vì sự đơn giản mà các designers chuyên nghiệp thích dùng nó hơn cả các phần mềm có trả phí của Adobe như Ai hay Ps, dù nó là miễn phí. Trong quá trình chờ đợi bài viết tiếp theo về vector drawable compat, bạn có thể tải Inkscape về để nghịch ngợm và tập tành thiết kế. Chúc các bạn vẽ vời vui vẻ.

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.