Android Bài 21: Sử Dụng Drawable – Ảnh 9-Patch & Ảnh Vector

Posted by
Rating: 5.0/5. From 16 votes.
Please wait...

Được chỉnh sửa ngày 22/10/2019.

Chào mừng các bạn đã đến với bài học Android thứ 21, bài học về cách sử dụng ảnh 9-Path và ảnh Vector. Đây là bài học trong chuỗi bài viết về lập trình ứng dụng Android bằng Java của Yellow Code Books.

Với bài học hôm trước, bạn đã làm quen với cách sử dụng resource drawable (resource ảnh) đầu tiên của Android, đó là dùng đến ảnh bitmap. Có đến hơn 90% trường hợp bạn sẽ dùng đến ảnh bitmap này trong xây dựng ứng dụng Android (theo thống kê không rõ nguồn gốc của mình). Tuy nhiên có đôi lúc bạn bị “bất lực” trong một số tình huống sử dụng ảnh bitmap, hoặc bạn muốn tìm kiếm một định dạng ảnh nào đó linh động hơn. Thì bài học hôm nay sẽ giúp bạn trả lời hai câu hỏi đó, bạn sẽ làm quen với hai loại ảnh khá “chất”, nhưng hơi khó sử dụng với các bạn mới làm quen với Android xíu, đó là ảnh 9-Patch và ảnh vector.

Chú ý là các bài ví dụ hôm nay mình đều lấy source code hiện tại của TourNote ra để làm mẫu. Nếu bạn nào chưa có thực hành TourNote ngày nào thì có thể down source code về từ link này, hoặc bạn có thể tự tạo project mới hoàn toàn.

Ảnh 9-Patch

Dạng ảnh linh động hơn bitmap đầu tiên mà mình muốn chia sẻ có cái tên là 9-Patch, hay một số nơi viết là Nine-Patch. Còn đọc lên thì bạn đừng đọc là “chín pát-ch” mà hãy đọc luôn là “nai-n pat-ch”. Đúng như tên gọi, ảnh này được chia nhỏ làm “9 miếng”. Thực chất thì bản thân ảnh này cũng là một ảnh PNG, nhưng bạn cần phải chỉ định miếng nào trong ảnh được phép co giãn, miếng nào phải giữ nguyên kích thước so với thiết kế ban đầu. Rồi sau đó, khi thực thi ở môi trường thực tế, hệ thống sẽ dựa vào các thiết lập của các miếng đó mà sẽ mang đến cho ứng dụng của chúng ta một cách thức sử dụng PNG khác hoàn toàn so với cách cũ.

Cấu Tạo Của Ảnh 9-Patch

Đầu tiên, một ảnh được gọi là ảnh 9-Patch nếu chúng được lưu trữ với đuôi là .9.png. Bạn xem, ảnh này đúng là ảnh PNG, nhưng có thêm số 9 ở trước, nhìn vào phần đuôi này mà hệ thống Android sẽ hiểu bạn đang sử dụng ảnh PNG dạng 9-Patch chứ không phải PNG của bitmap ở bài trước.

Để tạo ra ảnh .9.png, bạn (hay designer, hay Google cũng có tool cho bạn làm điều này) phải chừa ra 1 pixel cho mỗi cạnh của ảnh PNG gốc. 1 pixel này sẽ dùng để định nghĩa miếng nào có thể co giãn được, miếng nào không nên co giãn, rồi vẽ vào phần chừa ra đó một hay nhiều lằn gạch màu đen. Như hình minh họa sau của Google.

Cấu tạo của ảnh 9-Patch
Cấu tạo của ảnh 9-Patch

Như hình minh họa trên, thì cái khối vuông với bốn cạnh bo tròn ở cả hai hình trên và dưới là một background cho một Button nào đó. Giả sử bạn không định nghĩa 9-Patch (không có các lằn gạch ở các bên như hình), thì khi background này co giãn theo kích cỡ của Button, các góc bo tròn của nó sẽ bị biến dạng. Còn với định nghĩa 9-Path, bạn có thể chỉ định sao cho các góc sẽ được giữ nguyên vẹn, để biết cách thức chỉ định ra sao thì bạn có thể đọc tiếp thông tin dưới đây.

Để giải thích cho việc các đường gạch sẽ tạo nên một ảnh 9-Path thế nào. Thì bạn xem, ở hình trên cùng, bạn chú ý vào hai đường gạch đen ở trên và trái của ảnh. Các đường gạch đen này giúp chỉ định những vùng được phép co giãn theo chiều dài và rộng của ảnh tương ứng. Mình minh họa hình dưới cho bạn thấy 9 miếng của ảnh PNG được tạo ra như thế nào từ sự kết hợp hai đường gạch đen này. Trong đó thì các miếng có màu hồng (các miếng số 2, 4, 5, 6, 8) sẽ được phép co giãn thoải mái khi chương trình được chạy lên, các miếng còn lại (các miếng số 1, 3, 7, 9) thì được giữ nguyên. Nhờ định nghĩa như vậy mà bạn có thể bảo toàn kích thước của các vùng có góc bo tròn. Đến bước này bạn đã hiểu cách hoạt động của 9-Path rồi đúng không nào. Tuy nhiên mình chỉ mới nói đến 2 đường gạch đen ở trên và trái thôi, 2 đường còn lại như thế nào thì mời bạn xem tiếp bên dưới.

Bạn đã thấy 9 miếng được định nghĩa ra từ 2 đường gạch trên-trái ảnh chưa nào
Bạn đã thấy 9 miếng được định nghĩa ra từ 2 đường gạch trên-trái ảnh chưa nào

Tiếp tục, mình nói về hai đường gạch đen bên phải và dưới của ảnh. Các đường phải và dưới này không dùng để chỉ định việc co giãn của ảnh nữa, mà giúp chỉ định nội dung (như text hay hình ảnh khác) nếu để vào widget có dùng ảnh 9-Patch này, sẽ được canh chỉnh như thế nào. Hai đường gạch ở trường hợp này là không bắt buộc, bạn có thể để trống nếu muốn sự canh chỉnh nội dung được thực hiện theo mặc định hoặc theo các thuộc tính XML mà bạn đã từng sử dụng.

Bạn sẽ hiểu rõ hơn về các đường định nghĩa cho ảnh 9-Patch này qua ví dụ của mình ở bên dưới.

Ví Dụ Cần Sử Dụng Ảnh 9-Patch

Để dễ hiểu nhất, mình đưa ra một ví dụ cực kỳ thực tế.

Giả sử designer đưa cho bạn một giao diện, và mong muốn bạn thiết kế với một EditText giống như dưới đây.

Ví dụ giao diện buộc phải sử dụng ảnh 9-Patch
Ví dụ giao diện buộc phải sử dụng ảnh 9-Patch

Nếu là bạn, gặp thiết kế như trên, mình khuyên bạn nên xin designer một background như dưới đây.

Chỉ cần xin designer background như này
Chỉ cần xin designer background như này

Bạn có thể thấy, background mà bạn xin là một khung vuông, khung vuông này có sẵn 4 góc bo tròn, và có bao gồm cả hình cái kính lúp luôn. Nếu bạn không dùng đến ảnh 9-Path, mà hiển thị ảnh PNG này làm background của EditText luôn, bạn sẽ thấy 2 điều tệ hại. Một là người dùng sẽ gõ chữ đè lên cả cái kính lúp, chúng ta mong muốn chữ phải xuất hiện bên phải kính lúp cơ. Và hai là các góc bo tròn của khung này sẽ bị kéo dãn ra rất xấu. Mình làm thử cho bạn xem điều tệ hại này.

<EditText
    android:id="@+id/activity_main_edt_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:hint="Search your place"
    android:background="@drawable/bg_edt_search" />
after
Điều tệ hại nếu không dùng ảnh 9-Path

Bạn thấy chưa, UI trở nên rất xấu. Thế nhưng, trước khi đi vào chi tiết cách thức tạo một ảnh 9-Patch như thế nào, mình nói thêm một tí. Vì mình biết, bạn sẽ không phục nếu mình nói về 9-Path liền, bạn sẽ bảo, xời, có nhiều cách để làm mà, sao cứ phải 9-Path. Mình biết bạn có một cách khác như sau.

Bạn không xin designer background như mình đưa ra trên kia, mà nhờ designer tách dùm mấy thành phần UI ra. Đại loại cũng như dưới đây, để bạn có thể dễ dàng ráp nối chúng lại theo thiết kế. Trong đó ảnh cái kính lúp bạn sẽ dùng đến ImageView để hiển thị,  EditText đó với background bo tròn được hiển thị bên phải ImageView là xong.

search_separate

Uhm… cách này có thể làm được. Nhưng. Thứ nhất, nó sẽ làm bạn mất rất nhiều thời gian, vì bạn phải thao tác với nhiều ảnh hơn và tổ chức nhiều widget hơn. Và kết quả chắc chắn không như bạn mong muốn đâu, vì với hình bo góc ở bên phải mà bạn nhờ tách ra í, khi kéo dài quá (tùy theo kích cỡ màn hình) cũng sẽ gặp phải tình trạng các góc bo không còn còn đẹp nữa. Vậy chúng ta vẫn sẽ nên quay lại với 9-Patch thôi.

Tổ Chức Ảnh 9-Patch Trong res/

Ảnh 9-Patch thực chất cũng là một dạng ảnh trong nhóm drawable mà mình đang nói đến. Do đó giống như bên ảnh bitmap, bạn chỉ có thể để ảnh 9-Patch này vào thư mục res/drawable-xxx/. Đặc biệt hơn, mình khuyên các bạn để thẳng vào res/drawable/ luôn. Vì sao không cần chỉ định alternative resource cho chúng? Bởi đặc tính co giãn linh động của các ảnh 9-Patch, nên thường thì người ta chỉ cần tạo ra một ảnh, rồi chỉ định 9 miếng cho nó. Do chỉ có một ảnh thì để vào default resource luôn cho rồi.

Để bắt đầu xây dựng EditText, bạn hãy vào link này và download ảnh background PNG cho EditText về.

Ảnh down về để vào thư mục drawable luôn
Ảnh down về để vào thư mục drawable luôn

Công Cụ Giúp Chuyển Ảnh PNG Sang Ảnh 9-Patch

Bạn vừa down về ảnh PNG thôi, chúng ta sẽ tạo ra ảnh 9-Patch như thế nào? Có nhiều cách để hô biến một ảnh PNG sang 9-Patch. Như trường hợp của mình, đôi khi lười, mình nhờ luôn các bạn designer thiết kế các đường gạch đen, rồi đổi đuôi file thành .9.patch, hệ thống tự hiểu. Cách nữa là bạn tự thiết kế bằng các công cụ chỉnh sửa ảnh. Tuy nhiên mình có một tin vui rằng Android Studio cũng hỗ trợ chúng ta một công cụ được tích hợp sẵn, giúp chúng ta tạo ra ảnh 9-Patch một cách cực kỳ dễ dàng.

Với ảnh bg_edt_search.png bạn đã để vào thư mục res/drawable/, bạn click phải chuột vào nó và chọn Create 9-Patch file….

Nơi chọn đến công cụ tạo ảnh 9-Path
Nơi chọn đến công cụ tạo ảnh 9-Path

Popup sau đó xuất hiện hỏi bạn muốn save ảnh .9.png ở đâu và tên gì. Mình để như mặc định (tên là bg_edt_search.9.png và vẫn để ở res/drawable/).

Popup hỏi nơi chứa và tên của ảnh 9-Path
Popup hỏi nơi chứa và tên của ảnh 9-Path

Khi bạn nhấn OK ở popup trên, bạn sẽ thấy hai ảnh bg_edt_search.pngbg_edt_search.9.png cùng xuất hiện bên trong thư mục res/drawable/ của bạn. Bạn nên xóa ảnh .png gốc đi nhé, chỉ còn lại ảnh .9.png vừa tạo. Vì ở bài trước mình có nói, không thể có hai ảnh cùng tên (mặc dù khác đuôi) bên trong project của bạn được.

Giờ thì bạn click đúp vào bg_edt_search.9.png ở Android Studio lên. Editor của Android Studio khá thông minh, nó biết bạn đang mở ảnh 9-Patch chứ không phải PNG thường, nên giao diện của nó sẽ như sau.

Cụ thể công cụ tạo ảnh 9-Path
Cụ thể công cụ tạo ảnh 9-Path

Với cửa sổ như trên. Thì khung bên trái cho phép bạn chỉ định các vạch đen 1 pixel xung quanh hình gốc. Khung bên phải cho bạn xem trước kết quả khi co giãn theo các hướng (dọc, ngang, hay cả hai hướng) để bạn có cái nhìn tổng thể. Bạn có thể chỉ định độ zoom của khung bên trái hoặc độ co giãn ở khung bên phải bằng hai thanh trượt ở phía dưới hai khung này. Các checkbox trong popup cũng rất dễ hiểu, bạn cứ click xem thử nhé, nó không làm thay đổi ảnh của bạn đâu, chỉ giúp bạn có cái nhìn tốt hơn khi tương tác với ảnh mà thôi.

Bạn hãy tập trung vào ảnh ở khung bên trái. Hãy đưa chuột vào một pixel ở các biên, nhớ phải cẩn thận vì chỉ có một pixel mà thôi. Bạn có thể kéo một đường dài để định nghĩa các vạch cho 9-Patch. Bạn có thể click chuột vào bất cứ đâu trên phần một pixel đó để vẽ thêm các điểm, hoặc giữ phím Shift và click vào bất cứ nơi nào đã có điểm đen để xóa nó đi. Như mình có nói, bất cứ nơi nào ở đường biên trên và trái đều là chỉ định vùng có thể co giãn, còn đường biên phải và dưới là chỉ định nội dung xuất hiện như thế nào. Bạn hãy nhìn ảnh thiết kế 9-Patch của mình.

Ví dụ về ảnh 9-Path của mình
Ví dụ về ảnh 9-Path của mình

Với vạch ở trên, mình muốn “né” kính lúp ra, chỉ có phần thuộc bên phải kính lúp là được phép co giãn. Với vạch ở trái, mình cũng né cái kính lúp này bằng chỉ định hai đường trên và dưới cái kính. Vạch dưới và phải mình muốn nội dung của EditText rơi vào cái khung bên phải kính lúp, và ở giữa khung theo chiều dọc. Bạn đã hiểu đúng không nào. Bạn nên nhớ là các vạch bên phải và dưới là không bắt buộc nhé, với ví dụ này mình cố tình mang ảnh này ra để làm khó, để bạn có cơ hội vận dụng tất cả các vạch, còn như nếu không có kính lúp bên trái hình, thì nội dung sẽ nằm ở giữa EditText, thì khi đó bạn không cần chỉ định hai vạch phải và dưới này.

“Toàn cảnh” editor sau khi bạn chỉ định 9-Patch như dưới đây, bạn có thể thấy các ảnh xem trước bên khung phải của editor này cho ra các ảnh với độ co giãn tốt hơn rất nhiều so với trước khi bạn chỉ định 9-Patch đúng không, kết nhất là cái kính lúp luôn tròn trịa dù bị giãn ở chiều nào đi nữa.

Xem lại toàn cảnh ảnh 9-Path
Xem lại toàn cảnh ảnh 9-Path

Truy Xuất Đến Ảnh 9-Patch

Do việc sử dụng ảnh 9-Patch không khác so với sử dụng ảnh bitmap ở bài học hôm trước. Nên việc truy xuất đến ảnh 9-Patch này cũng tương tự. Do đó ở bước này bạn hoàn toàn có thể chạy lại project và xem kết quả mà không cần chỉnh sửa gì cho file XML ban đầu cả.

Kết quả cuối cùng
Kết quả cuối cùng

Ảnh Vector

Có thể nói rằng mình đã khá phấn khích với việc Android hỗ trợ ảnh vector. Về cơ bản thì ảnh vector có cấu trúc khác hoàn toàn với ảnh bitmap.

Nếu như ảnh bitmap được cấu thành bởi ma trận các điểm ảnh (cố định). Bạn có thể tưởng tượng giả sử có một ảnh bitmap có kích cỡ 100 x 100 pixel sẽ được biểu diễn bởi ma trận 100 x 100 điểm ảnh. Do đó nếu bạn muốn hiển thị ảnh này với kích cỡ lớn hơn, chẳng hạn như 400 x 400 pixel, thì các pixel này bị giãn nở ra, kết quả cho ta một ảnh bị vỡ. Chính vì đặc tính này của bitmap, mà bạn phải để nhiều kích thước ảnh vào trong các alternative resource khác nhau, để hạn chế tỉ lệ vỡ ảnh do sự co giãn này.

Qua đến ảnh vector, các ảnh dạng này không dùng ma trận tĩnh các điểm ảnh nữa, mà chỉ lưu trữ các thông số chỉ định các đường thẳng, đường cong, màu sắc… cho mỗi ảnh. Đến khi sử dụng ảnh dạng này ở thực tế, thì hệ thống mới chính thức vẽ ảnh lên màn hình dựa vào các thông số đó. Chính vì đặc tính này mà ảnh Vector không bị vỡ dù cho được biểu diễn với bất kỳ kích thước nào.

Ảnh vector tốt như vậy, thì bạn có thể tưởng tượng ra một điều rằng tất cả các project hiện nay đều tập trung vào sử dụng nó? Tuy nhiên, đời không như mơ, và cho dù ảnh vector có biết bao nhiêu là điều tốt đẹp, như là hiển thị đẹp hơn này, tốn ít thời gian để tổ chức ảnh vào các thư mục hơn này, và thậm chí file .apk sau khi xuất xưởng cũng nhẹ nữa này, nhưng ảnh dạng này vẫn còn bị các lập trình viên dè dặt khi sử dụng. Nguyên nhân vì sao thì chúng ta cùng điểm qua một vài bất lợi của chúng, để bạn có một quyết định rõ ràng nhất nếu muốn sử dụng chúng nhé.

  • Bất lợi đầu tiên có thể kể đến là, do ảnh vector được hệ thống vừa đọc thông số vừa vẽ lên màn hình, nên yêu cầu CPU xử lý nhiều hơn so với ảnh bitmap. Điều này làm cho ứng dụng có nhiều ảnh vector sẽ xử lý có vẻ chậm chạp hơn (điều này còn tùy vào số lượng ảnh vector được vẽ lên màn hình cùng lúc). Chính vì vậy mà Google khuyến cáo bạn nên giới hạn kích thước của ảnh dạng này ở 200 x 200 dp khi thiết kế lên UI.
  • Bất lợi kế tiếp là, không phải ảnh vector nào đưa vào Android thì hệ thống cũng chấp nhận. Bạn biết rồi đó, dù sao thì bộ xử lý của các thiết bị điện thoại cũng có giới hạn, chúng không thể xử lý các cấu trúc ảnh phức tạp được, do đó có nhiều ảnh vector khi đưa vào hệ thống sẽ bị báo lỗi, hoặc nếu không thì khi vẽ lên màn hình sẽ bị mất nét, mất điểm, nói chung là mất một số bộ phận.
  • Một bất lợi nữa, là ảnh dạng này không được hỗ trợ từ Android 4.4 (API level 20) trở về trước. Vậy nếu bạn vẫn muốn sử dụng ảnh vector cho tất cả các hệ điều hành trước và sau API level 20? Thì bạn hãy xem và chọn lựa cách thức tương thích ngược ở mục ngay dưới đây.

Vấn Đề Tương Thích Ngược

Vấn đề này xảy ra nếu bạn có khai báo minSdkVersion trong file build.gradle nhỏ hơn 21. Tất nhiên rồi, đa số các project hiện nay vẫn còn hỗ trợ các hệ điều hành Android trước 5.0.

Khi đó hoặc là bạn chấp nhận cho công cụ Vector Asset Studio mà mình sắp nói đến bên dưới, sẽ tạo ra (sau khi build) hai loại ảnh, một là PNG bình thường để có thể chạy với các hệ điều hành API level 20 trở về trước, và một là ảnh vector để chạy trên các hệ điều hành có API level 21 trở về sau. Hai là bạn chỉ định có sử dụng Support Library trong file build.gradle, thì thư viện này sẽ hỗ trợ cho bạn các hàm sử dụng hoàn toàn ảnh vector trong project, tùy bạn chọn thôi. Mình sẽ nói luôn chi tiết cách sử dụng hai cách này.

Chấp Nhận Vector Asset Studio Tạo Ra Hai Loại Ảnh

Với cách này thì bạn không làm gì cả, cứ đọc tiếp các phần tổ chức và tạo ảnh vector bên dưới của mình. Nhưng như bạn biết thì cách này sẽ tạo ra trong file .apk của bạn các ảnh PNG bên cạnh các ảnh vector, vậy thì chắc chắn file .apk này sẽ “phình to” hơn rồi, tùy vào số lượng ảnh vector mà bạn sử dụng.

Sử Dụng Support Library

Nếu bạn dùng cách này, thì trước khi đọc các phần bên dưới của mình, bạn hãy mở file build.gradle cấp độ module lên và thêm vào dòng được tô sáng như sau nhé.

apply plugin: 'com.android.application'
 
android {
    compileSdkVersion 25
    buildToolsVersion '25.0.2'
    defaultConfig {
        applicationId "com.yellowcode.tournote"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:design:25.3.1'
    compile 'com.android.support:recyclerview-v7:25.3.1'
}

Tổ Chức Ảnh Vector Trong res/

Bạn nên để các ảnh vector này trong thư mục res/drawable/. Vì cũng giống như ảnh 9-Patch, các ảnh vector này sẽ tự co giãn khi hiển thị thực tế, nên chúng ta không cần tổ chức chúng theo alternative resource nữa.

Có hai dạng ảnh vector được Android hỗ trợ, đó là SVG (Scalable Vector Graphic)PSD (Adobe Photoshop Document). Nhưng mình quen dùng SVG, dạng ảnh PSD mình chưa từng sử dụng qua.

Hiện tại do chưa có ảnh vector nào để bạn đặt vào trong thư mục này. Thôi thì chúng ta cùng qua bước dưới đây để có một resource vector nhé.

Công Cụ Vector Asset Studio

Bạn có nhớ ở bài về ảnh bitmap có nói đến công cụ Image Asset? Vậy thì bài hôm nay cũng có Vector Asset, cách sử dụng công cụ này cũng na ná như Image Asset vậy.

Để sử dụng Vector Asset, từ Android Studio, bạn click phải chuột vào thư mục res/ và chọn New > Vector Asset. Như hình.

Đường dẫn đến công cụ Vector Asset
Đường dẫn đến công cụ Vector Asset

Popup xuất hiện sau đó trông như thế này.

Popup Configure Vector Asset
Popup Configure Vector Asset

Bạn có thể thấy rằng giao diện của popup này khá tương đồng với Image Asset của bài hôm trước. Mình nói sơ qua một số thành phần của popup này.

  • Asset Type – Giúp bạn chọn giữa bộ vector icon có sẵn của Google (nếu check Clip Art), hay là từ file bạn upload lên (nếu check Local File).
  • Name – Chỉ là đặt tên cho icon thôi.
  • Clip Art – Click vào hình con robot ở mục này sẽ dẫn bạn đến một bộ các icon có sẵn của Google. Nhưng nếu ở trên kia bạn chọn vào Local File thì field này đổi tên là Patch, cho phép bạn chỉ định file vector của bạn.
  • Size – Chỉ định kích thước của file, bạn yên tâm rằng với ảnh vector, bạn có thể co giãn thoải mái, nên kích thước này cũng chỉ là tương đối, nếu có ảnh hưởng chăng, thì sẽ ảnh hưởng đến cách tương thích ngược có dùng chung ảnh PNG với ảnh vector mà mình nói ở trên kia.
  • Color – Thường các ảnh Vector là các ảnh đơn sắc. Nên chúng cho phép bạn chỉ định màu sắc chủ đạo của ảnh.
  • Opacity – Chỉ định độ trong suốt của ảnh. Mặc định giá trị 100% có nghĩa là không trong suốt.
  • Enable auto mirroring for RTL layout – Check vào nếu bạn muốn ảnh hỗ trợ tự động đảo ngược cho các quốc gia sử dụng hệ chữ được viết từ phải qua trái.

Bạn click vào hình con robot ở mục Clip Art nhé, popup xuất hiện sau đó bạn hãy tìm đến và chọn hình sau đây, hoặc bất cứ hình nào bạn thích. Sau khi nhấn OK ở popup chọn hình, thì bạn hãy đặt lại tên là empty_note_vector và nhấn Next.

Chọn icon mà bạn thích
Chọn icon mà bạn thích

Màn hình sau đó chỉ giúp bạn xác nhận lại ảnh sẽ được để ở đâu. Bạn cứ nhấn Finish để hoàn thành.

Lúc này đây bạn sẽ thấy xuất hiện một ảnh có tên empty_note_vector.xml. Bạn có thể click đúp vào để xem thử, bạn thấy không, ảnh này chỉ toàn là các thông số, đến khi ứng dụng được chạy thực sự, thì hệ thống mới dựa vào đây mà vẽ ảnh cho bạn.

Sử Dụng Ảnh Vector

Sử Dụng Ảnh Vector Từ File XML

Nếu bạn muốn sử dụng đến ảnh vector từ XML, thì còn tùy vào cách bạn chọn lựa phương án tương thích ngược trên kia nữa.

Nếu Bạn Đã Chấp Nhận Vector Asset Studio Tạo Ra Hai Loại Ảnh

Với chọn lựa này, như mình có nói, bạn không cần quan tâm gì ráo, bạn cứ truy xuất đến ảnh thông qua @drawable/tên_file như bình thường. Hệ thống sẽ quyết định là ảnh PNG hay ảnh vector sẽ được sử dụng ở môi trường thực tế. Với cách này bạn hãy vào lại activity_main.xml của TourNote và set ảnh cho ImageView như sau.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yellowcode.tournote.MainActivity">
 
    <TextView
        android:id="@+id/activity_main_tv_empty"
        style="@style/InformationTextView"
        android:layout_centerInParent="true"
        android:text="@string/mainscreen_empty_note" />
 
    <ImageView
        android:layout_width="@dimen/empty_icon_width"
        android:layout_height="@dimen/empty_icon_height"
        android:layout_below="@id/activity_main_tv_empty"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/padding_medium"
        android:scaleType="fitCenter"
        android:src="@drawable/empty_note_vector" />
 
</RelativeLayout>

Nếu Bạn Đã Chấp Nhận Sử Dụng Support Library

Cách này sẽ không có ảnh PNG cho các hệ điều hành Android level 20 trở về trước, mà chỉ toàn các ảnh vector mà thôi. Do đó để các hệ điều hành Android cũ có thể hiểu được các ảnh vector này, bạn phải dùng đến thuộc tính app:srcCombat thay cho android:src ngày xưa. Như thế này.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yellowcode.tournote.MainActivity">
 
    <TextView
        android:id="@+id/activity_main_tv_empty"
        style="@style/InformationTextView"
        android:layout_centerInParent="true"
        android:text="@string/mainscreen_empty_note" />
 
    <ImageView
        android:layout_width="@dimen/empty_icon_width"
        android:layout_height="@dimen/empty_icon_height"
        android:layout_below="@id/activity_main_tv_empty"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/padding_medium"
        android:scaleType="fitCenter"
        app:srcCompat="@drawable/empty_note_vector" />
 
</RelativeLayout>

Truy Xuất Từ Java Code

Mình thì mình thấy không có gì khác biệt khi dùng ảnh vector ở Java Code đối với hai cách hỗ trợ như trên. Bằng cách truyền vào tham số R.drawable.tên_file cho các hàm cần một resource ID, giống như đã từng làm với ảnh PNG bình thường vậy.

ImageView imvTest = (ImageView) findViewById(R.id.imvTest);
imvTest.setImageResource(R.drawable.empty_note_vector);

Trên đây là hai cách sử dụng ảnh drawable khác bên cạnh ảnh bitmap truyền thống mà Android hỗ trợ cho lập trình viên chúng ta. Cách nào cũng có điểm mạnh và điểm yếu riêng cả. Tùy vào từng trường hợp mà bạn sẽ phải đưa ra quyết định xem project của bạn cần sử dụng ảnh loại nào, đừng quá cứng nhắc trong việc chỉ sử dụng một loại ảnh thôi, trong một project hoàn toàn có thể có nhiều thể loại ảnh drawable khác nhau. Tất nhiên các thể loại ảnh mà Android hỗ trợ cho chúng ta vẫn chưa dừng lại ở đây, bài học sau chúng ta sẽ tiếp tục nói nhiều hơn về resource drawable này.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy ủng hộ blog bằng cách:

Đánh giá 5 sao ở mỗi bài nếu thấy thích.
Comment bên dưới mỗi bài nếu có thắc mắc.
Để lại địa chỉ email của bạn ở thanh bên phải để nhận được thông báo sớm nhất khi có bài viết mới.
Chia sẻ các bài viết của Yellow Code Books đến nhiều người khác.

Bài Kế Tiếp

Lại tiếp tục nói về các resource drawable, cụ thể là cách sử dụng ảnh dạng Shape XML và ảnh dạng Layer List.

5 comments

  1. Ad ra bài tiếp đi ạ, em sắp báo cáo rồi ad :((

    Rating: 5.0/5. From 1 vote.
    Please wait...
    1. Chỉ sợ không kịp cho bạn Phương làm báo cáo 😀 Kiến thức Android đến bài học hôm nay trong blog của mình còn sơ đẳng lắm, nếu bạn cần tìm hiểu kiến thức nào cho báo cáo của bạn thì có thể gởi mail cho mình.

      No votes yet.
      Please wait...
      1. Ad cho em xin địa chỉ mail với ạ, cảm ơn ad!

        No votes yet.
        Please wait...
      2. Bạn Phương có thể gởi mail về yellowcode.books@gmail.com. Hoặc qua bên tab Liên Hệ của trang web này mà điền nội dung vào rồi nhắn nút Gửi, sẽ nhanh hơn.

        No votes yet.
        Please wait...

Gửi phản hồi