Android Làm Việc Với SVG / vector drawables
Bài đăng này đã không được cập nhật trong 3 năm
Trong khi phát triển các ứng dụng android, việc hỗ trợ nhiều thiết bị với những độ phân giải khác nhau đôi khi trở thành cơn ác mộng đối với những nhà phát triển ứng dụng. Việc bao gồm nhiều image cho những độ phân giải khác nhau sẽ làm tăng kích thước của project. Giải pháp ở đây là sử dụng đồ hoạ véc to (Vector Graphics ) chẳng hạn như SVG images. Trong khi android vẫn chưa hỗ trợ SVGs (Scalable Vector Graphics) trực tiếp với sự ra mắt của Lollipop một class mới đã được giới thiệu gọi là VectorDrawable cái này cho phép những nhà thiết kế, những nhà phát triên vẽ những image giống nhau chỉ sử dụng duy nhất code. Giải thích đơn giản một chú Đồ hoạ vector là cách miêu tả những thành phần đồ hoạ bằng cách sử dụng các hình dạng hình học .
VectorDrawable là gì ?
Cái tên nói lên tất cả, vector drawables là dưạ trên đồ hoạ vector, đồ hoạ véctor là một cách mô tả các thành phần đồ hoạ sử dụng cách hình dạng hình học. Nó tương tự như một file SVG. Trong android VectorDrawable được tạo ra như là một file XML. Bây giờ không cần tạo ra những image với các size khác nhau cho mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi ... Chúng tôi cần duy nhất một file vector cho tất cả các divice với những độ phân giải khác nhau. Ngoài ra cho các version android cũ hơn không hỗ trợ vector drawables, Vector Asset Studio có thể biến các vector drawables của bạn vào các kích thước bitmap khác nhau cho mỗi mật độ màn hình khi chạy. Ở đây là chi tiết thông tin Vector Asset Studio.
Tạo Android Project
Tạo một project android Mở build.gradle trong app module, thêm dòng code bên dưới vào khối defaultConfig .
vectorDrawables.useSupportLibrary = true
file build.gradle của chúng ta sẽ như này:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "info.androidhive.vectordrawable"
minSdkVersion 17
targetSdkVersion 25
versionCode 1
versionName "1.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(dir: 'libs', include: ['*.jar'])
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.1.0'
testCompile 'junit:junit:4.12'
}
nếu bạn đang sử dụng gradle version dưới 2.0 thì như bên dưới
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "info.androidhive.vectordrawable"
minSdkVersion 17
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
generatedDensities=[]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
aaptOptions {
additionalParameters "--no-version-vectors"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
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:24.2.1'
testCompile 'junit:junit:4.12'
}
Tạo VectorDrawable Từ Material Icons.
Vậy chúng ta hãy bắt đầu tạo VectorDrawables từ Material Icons (Material Icons là bộ icon chính thức từ Google đã được thiết kế dưới material design guidelines, những icon là mã nguồn mở, đẹp và dễ dàng sử dụng trong các project web, android, hay iOS). Trong Project** click chuột phải **trên thư mục drawable Đi tới New ⇒ Vector Asset
Click trên launch icon và duyệt Material Icons
Lựa chọn một icon bạn thích rồi click ok
Review name của file sau đó click **next ** Bây giờ Vector Asset Studio sẽ hiển thị vị trí về nơi file đã được save , review nó và click finish Folder drawable bây giờ bao gồm một file mới tạo và bên dưới sẽ là code của nó
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="35dp"
android:height="35dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFe29069"
android:pathData="M2.5,19h19v2h-19zM22.07,9.64c-0.21,-0.8 -1.04,-1.28 -1.84,-1.06L14.92,10l-6.9,-6.43 -1.93,0.51 4.14,7.17 -4.97,1.33 -1.97,-1.54 -1.45,0.39 1.82,3.16 0.77,1.33 1.6,-0.43 5.31,-1.42 4.35,-1.16L21,11.49c0.81,-0.23 1.28,-1.05 1.07,-1.85z"/>
</vector>
Bạn có thể chỉnh sửa chiều rộng (width) và chiều cao (height) của vector theo ý muốn của bạn ,bởi mặc định nó sẽ là 24dp. Một vector có thể bao gồm một hoặc nhiều path. mỗi path có thể bao gồm nhiều thuộc tính trong số đó fillColor và pathData là quan trọng nhất. fillColor là thuộc đính đinh nghĩa color của path, nó phải là một thuộc tính màu (có thể là 1 mã màu như này #aarrggbb hoặc là được trỏ tới resource color) . pathData là định nghĩa hình dạng đường. Trong trường hợp này tôi sẽ chỉnh sửa width, height, fillColor
Tạo VectorDrawable Từ SVG or PSD
Ngoài việc tạo vectorDrawable từ Material Icon chúng ta có thể tạo nó từ SVG or PSD. Tuy nhiên nó cũng có một vài hạn chế ,bạn có thể kiểm tra thêm https://developer.android.com/studio/write/vector-asset-studio.html#PSD . Trong Project click chuột phải thư mục drawable Tiếp New ⇒ Vector Asset Click trên radio button Local File (SVG, PSD) Click trên browse icon và chuyển hướng tời file SVG or PSD file lựa chọn nó Sau đó click OK Kiểm tra image trong preview và click Next ⇒ Finish. Bên dưới là file code được generate từ svg
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportHeight="512.0"
android:viewportWidth="512.0">
<path
android:fillColor="#273B7A"
android:pathData="M256,256m-256,0a256,256 0,1 1,512 0a256,256 0,1 1,-512 0" />
<path
android:fillColor="#121149"
android:pathData="M506.4,309.5L300.1,103.3l-62.2,113.4l2.3,44.8l82.5,82.5l-3.4,3.4l-35.8,-35.8l-45.6,2.9h-64.7l-66.7,105.5l83.6,83.6C211.2,509 233.2,512 256,512C379,512 481.8,425.2 506.4,309.5z" />
<path
android:fillColor="#FFEDB5"
android:pathData="M401.6,290.3c-3.3,-4.6 -9.3,-6.4 -14.6,-4.4c-0.1,0 -0.2,0.1 -0.2,0.1l-89.6,29.8c0,0.7 0,1.4 -0,2.2c-0.7,11.4 -9.6,20.6 -21,21.8l-54,5.6c-3.4,0.4 -6.5,-2.1 -6.8,-5.5c-0.4,-3.4 2.1,-6.6 5.5,-6.8l54,-5.6c5.3,-0.6 9.5,-4.9 9.8,-10.2c0.2,-2.9 -0.8,-5.8 -2.7,-8c-1.9,-2.2 -4.6,-3.5 -7.6,-3.7l-71.7,-4.7c-8.1,-0.5 -16,1.3 -23.1,5.1L85,358l25.6,51.6l23.8,-20.7c10.1,-8.8 23.5,-12.6 36.7,-10.4l79.4,13.2c14.6,1.9 29.1,-1.7 41.1,-10.2l108.1,-74.5C404.5,302.8 405.4,295.5 401.6,290.3z" />
<path
android:fillColor="#FEE187"
android:pathData="M274.9,327.4c5.3,-0.6 9.5,-4.9 9.8,-10.2c0.2,-2.9 -0.8,-5.8 -2.7,-8c-1.9,-2.2 -4.6,-3.5 -7.6,-3.7l-15.9,-1v24.7L274.9,327.4z" />
<path
android:fillColor="#FEE187"
android:pathData="M401.6,290.3c-3.3,-4.6 -9.3,-6.4 -14.6,-4.4c-0.1,0 -0.2,0.1 -0.2,0.1l-89.6,29.8c0,0.7 0,1.4 -0,2.2c-0.7,11.4 -9.6,20.6 -21,21.8l-17.7,1.8v50.6c11.8,-0.1 23.3,-3.8 33.1,-10.7l108.1,-74.5C404.5,302.8 405.4,295.5 401.6,290.3z" />
<path
android:fillColor="#FFC61B"
android:pathData="M317.4,146c0,-34.7 -28.9,-62.8 -63.9,-61.4c-31.4,1.2 -57.1,26.5 -58.9,57.9c-1.2,21.6 8.7,40.9 24.6,52.7c10.1,7.6 16.3,19.2 16.3,31.9v21.3c0,11.3 9.2,20.5 20.5,20.5l0,0c11.3,0 20.5,-9.2 20.5,-20.5V227.4c0,-12.8 6.2,-24.6 16.5,-32.3C307.8,183.9 317.4,166 317.4,146z" />
<path
android:fillColor="#EAA22F"
android:pathData="M255.4,84.6v184.2c0.2,0 0.4,0 0.6,0c11.3,0 20.5,-9.2 20.5,-20.5V227.4c0,-12.8 6.2,-24.6 16.5,-32.3c14.9,-11.2 24.5,-29 24.5,-49.1C317.4,111.9 289.6,84.3 255.4,84.6z" />
<path
android:fillColor="#A6A8AA"
android:pathData="M235.5,227.9v20.5c0,11.3 9.2,20.5 20.5,20.5l0,0c11.3,0 20.5,-9.2 20.5,-20.5v-20.5L235.5,227.9z" />
<path
android:fillColor="#808183"
android:pathData="M255.4,227.9v40.9c0.2,0 0.4,0 0.6,0c11.3,0 20.5,-9.2 20.5,-20.5v-20.5L255.4,227.9z" />
<path
android:fillColor="#FF5419"
android:pathData="M244.2,183.8c-1.1,0 -2.3,-0.3 -3.3,-1.1c-2.5,-1.8 -3,-5.3 -1.2,-7.8l17.1,-23.4H244.2c-2.1,0 -4,-1.2 -5,-3.1c-1,-1.9 -0.8,-4.1 0.5,-5.8l23.6,-32.3c1.8,-2.5 5.3,-3 7.8,-1.2c2.5,1.8 3,5.3 1.2,7.8L255.2,140.4h12.6c2.1,0 4,1.2 5,3.1c1,1.9 0.8,4.1 -0.5,5.8l-23.6,32.3C247.6,183 245.9,183.8 244.2,183.8z" />
<path
android:fillColor="#C92F00"
android:pathData="M272.3,117c1.8,-2.5 1.3,-6 -1.2,-7.8c-2.5,-1.8 -6,-1.3 -7.8,1.2l-7.9,10.8v18.9L272.3,117z" />
<path
android:fillColor="#C92F00"
android:pathData="M267.8,140.4h-12.4v11.2h1.4l-1.4,1.9v18.9l16.9,-23.1c1.2,-1.7 1.4,-3.9 0.5,-5.8C271.8,141.6 269.9,140.4 267.8,140.4z" />
<path
android:fillColor="#D35933"
android:pathData="M66.1,355.1l32.5,-22.2l40.5,64.7l-32.5,22.2z" />
<path
android:fillColor="#B54324"
android:pathData="M139.1,397.6l-20.5,-32.8l-32.4,22.5l20.4,32.6z" />
</vector>
Sử Dụng VectorDrawable
Chúng ta đã thành công trong việc thêm VectorDrawables tới project bây giờ là thời điểm sử dụng nó Mở file layout và thêm đoan code bên dưới vào file layout của bạn
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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="info.androidhive.vectordrawable.MainActivity">
<ImageView android:id="@+id/ic_logo"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:layout_marginTop="30dp"
app:srcCompat="@drawable/ic_light_bulb" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center_horizontal"
android:text="Tap on icon to change tint color" />
<android.support.v7.widget.AppCompatImageView
android:id="@+id/ic_android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp" />
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"
android:drawableLeft="@drawable/ic_flight_takeoff"
android:gravity="center_horizontal"
android:text="TextView with Vector Drawable" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Radio button with vector drawable icons" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:showDividers="middle"
android:orientation="horizontal"
android:gravity="center">
<android.support.v7.widget.AppCompatRadioButton
android:id="@+id/radioBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/radio_selector"
android:button="@android:color/transparent" />
<android.support.v7.widget.AppCompatRadioButton
android:id="@+id/radioBtn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/radio_selector"
android:button="@android:color/transparent" />
<android.support.v7.widget.AppCompatRadioButton
android:id="@+id/radioBtn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/radio_selector"
android:button="@android:color/transparent" />
<android.support.v7.widget.AppCompatRadioButton
android:id="@+id/radioBtn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/radio_selector"
android:button="@android:color/transparent" />
<android.support.v7.widget.AppCompatRadioButton
android:id="@+id/radioBtn5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/radio_selector"
android:button="@android:color/transparent" />
</RadioGroup>
</LinearLayout>
Layout ở trên sẽ tạo ra một màn hình giống như này: Sử dụng VectorDrawable với ImageView Từ xml Chúng ta hãy bắt đầu với ImageView bằng cách gắn một VectorDrawable tới ImageView thông qua xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_light_bulb"/>
Như bạn nhìn thấy , Tôi đã sử dụng app:srcCompat thay cho android:src, để cho support library làm phần còn lại là hiển thị image trên tất cả phiên bản android
Sử dụng VectorDrawable với ImageView từ Java Bây giờ chúng ta làm là gắn một VectorDrawable tới ImageView trong code java
public class MainActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final AppCompatImageView icAndroid = (AppCompatImageView) findViewById(R.id.ic_android);
icAndroid.setImageResource(R.drawable.ic_android);
icAndroid.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
icAndroid.setColorFilter(color);
}
});
}
}
Cho việc sử dụng VectorDrawable từ java hoặc sử dụng nó như là background you bạn khởi tạo AppCompatDelegate để cho phép compat vector từ tài nguyên.
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Bất kể khi nào bạn có dự định sử dụng VectorDrawable từ java hãy nhớ rằng sử dụng AppCompatView thay cho view bình thường như ở đây tôi sử dụng AppCompatImageView bây giờ gắn VectorDrawable như là src or background như bạn làm bình thường
AppCompatImageView icAndroid = (AppCompatImageView) findViewById(R.id.ic_android);
icAndroid.setImageResource(R.drawable.ic_android);
Ngoài ra các bạn có thể tham khảo thêm 1 bài viết khác của tôi nói về Tối ưu hiệu suất của Vector Drawables Trong Android
All rights reserved