Cách sử dụng Icon Fonts trong ứng dụng Android

Trong khi Developers tạo ra một ứng dụng có một trong những điều quan trọng phải chú ý ngay từ bước đầu đó là resource (icons), những định rạng quen thuộc mà chúng ta dùng nhiều nhất từ trước đến giờ như PNG, JPG, vector(xml). Khi mà ứng dụng của bạn càng lớn tức là tỉ lệ thuận với việc dùng resource của bạn tăng lên, tới lúc bạn sắp hoàn thành project của mình và quay lại nhìn drawable folder thì thật chóng mặt phải không nào ? 😄 Ok, vậy có cách nào mà giảm thiểu phần lớn các resource PNG hay JPG không? Và chỉ có những resource đặc biệt và đặc trưng ứng dụng như logo, banner, ... thì mới dùng PNG hoặc JPG. Câu trả lời là CÓ, mình giới thiệu cách dùng Icon Fonts để làm được điều trên. Nội dung chia sẻ là sử dụng FontAwesome

Icon font làm việc như thế nào ?

Thông thường nếu bạn dùng PNG trong drawable mà muốn support multi-screen device thì bạn cần phải ít nhất 4 version cho drawable hoặc nhiều hơn nữa. Nhưng chưa tính đến việc hiển thị icon đó trên smartphones có ultra-dense HD thì icon đó sẽ bị vỡ(xuất hiện hình răng cưa). Còn đối với font chúng ta thường nghĩ đó là characters dùng để viết, nhưng thực tế đó là shapes (hình khối) và Icon fonts ở đây không phải là hình khối tạo thành các chữ cái nữa mà là icons tùy vào typeface của font quy định. Vì vậy khi bạn muốn hiển thị kích thước lớn nó cũng không bị vỡ như PNG hay JPG.

Sử dụng icon font trong Apps

Bạn cần download FontAwesome Để vào assets folder của project.

  • Tiếp theo, tạo helper class FontManager.java
public class FontManager {
 
    public static final String FONTAWESOME = "fontawesome-webfont.ttf";
     
    public static Typeface getTypeface(Context context, String font) {
        return Typeface.createFromAsset(context.getAssets(), font);
    }    
 
}

Bạn có thể dùng với cách đơn giản :

yourTextView.setTypeface(FontManager.getTypeface(FontManager.FONTAWESOME));

Nhưng chưa tốt ở chỗ bạn phải dùng với từng TextView một, thường trong mỗi màn hình sẽ có nhiều icon (chính là những TextView) thì không được tốt. Đơn giản chúng ta nghĩ TextView sẽ được nằm trong những container là ViewGroup: LinearLayout, RelaytiveLayout, ... Sửa lại trong FontManager.java

public class FontManager {
 
    // ...
     
    public static void markAsIconContainer(View v, Typeface typeface) {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                markAsIconContainer(child);
            }
        } else if (v instanceof TextView) {
            ((TextView) v).setTypeface(typeface);
        }
    }
     
}
  • Bây giờ khi bạn muốn dùng icon font trong mỗi màn hình bạn chỉ cần thêm đoạn code dưới đây vào method onCreate của Activity:
Typeface iconFont = FontManager.getTypeface(getApplicationContext(), FontManager.FONTAWESOME);
FontManager.markAsIconContainer(findViewById(R.id.icons_container), iconFont);
  • Lựa chọn icon font mà bạn muốn sử dụng FontAwesome cheatsheet Thực chất mỗi icon ở đây đã được chuyển về dạng Unicode format rồi nên dù bạn muốn support cho CSS, HTML đều được. Bạn hãy lựa chọn icon phù hợp với ứng dụng mà bạn cần, copy đoạn characters trong phần [...] cuối mỗi icon:

  • Như ở đây mình chọn những icon này, để nó vào file strings.xml của bạn

  • Tạo một giao diện để dùng chúng thôi nhỉ ? Ví dụ:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="horizontal"
    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.iconfont.dinhviet.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/fa_icon_areachart" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/fa_icon_piechart" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/fa_icon_linechart" />
</LinearLayout>

  • Nếu bây giờ bạn mở Preview của Android Studio ra thì sẽ chẳng thấy gì, không có icon nào bạn chọn mà nó hiển thị nên ngay cả vì nó không phải là mặc định. Bạn build và run project sẽ thấy được kết quả như dưới đây !

- Câu hỏi: Icon Font có làm được điều gì khác không ? Khi mà PNG bạn chỉ dùng được 1 trạng thái nghĩa là image đó là màu vàng bạn không thể nào chuyển thành màu đỏ được, hay đang size 16x16px khi chuyển thành 100x100px sẽ bị vỡ. Nhưng icon font thì không như vậy.

  • Thử thay textSizetextColor vì bạn biết đấy chúng ta đang dùng TextView mà chứ có phải ImageView đâu 😄
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_weight="1"
    android:textSize="45sp"
    android:textColor="#9b59b6"
    android:text="@string/fa_icon_areachart" />

Bạn thay cho 2 icon còn lại nhé , và đây là kết quả demo:

Ưu thế của Icon Font

Như ở phần mở đầu bạn cũng đã tìm thấy một câu trả lời cho phần này rồi, mình cung cấp thêm một vài ưu thế khác nữa mà mình đã sử dụng.

  1. Scale dễ dàng
  2. Thay đổi màu sắc
  3. Thay đổi kích thước ( như ví dụ trên có rồi)
  4. Có những tính chất image có , ví dụ: xoay, opacity,..
  5. Chiếm dung lượng rất nhỏ so với việc dùng PNG . Và dĩ nhiên dung lượng apps sẽ giảm đi đáng kể, thêm vào đó số lượng file image trong drawable là rất ít.

Tổng kết

Hy vọng với bài viết trên đây đem lại sự hữu ích thêm cho các Developers để việc sử dụng resource tối ưu hơn, size application của bạn giảm thiểu đáng kể mà chất lượng icon hiển thị tốt trên multi-devices. Dưới đây là danh sách một số Icon fonts đang được dùng phổ biến để các bạn tìm hiểu thêm :

  • Font Awesome
  • Iconic
  • Signify Lite
  • Foundation
  • Symbolset
  • Pictos and Pictos Server