Sử dụng Drawables trong android studio

GIỚI THIỆU

Một drawable resource có thể vẽ được là một khái niệm chung cho một hình ảnh có thể được rút ra cho màn hình. Drawables được sử dụng để xác định shapes, colors, borders, gradients, , vv mà sau đó có thể được áp dụng cho các views bên trong Activity.

Một danh sách các dawable mặc định cho tất cả các phiên bản android. androiddrawables là một nơi chứa các tài liệu tham khảo tuyệt vời.

SỬ DỤNG

Drawables có thể được sử dụng trong các tình huống khác nhau như drawing shapes, setting state behaviors for buttons, creating stretchable button backgrounds and creating compound drawable layers.

Có ít nhất 17 loại drawables nhưng có năm loại quan trọng nhất :

  1. Shape Drawables – Định nghĩa một hình dạng với các đặc tính như stroke, fill, and padding
  2. StateList Drawables – Định nghĩa một danh sách các drawables
  3. LayerList Drawables – Định nghĩa một danh sách các drawables gom lại với nhau
  4. NinePatch Drawables – Một tập tin PNG v cho phép thay đổi kích thước thích hợp
  5. Vector Drawables – Defines complex XML-based vector images

Cùng tìm hiểu một số ví dụ về cách sử dụng:

Drawing Shapes

Shape Drawable là một file xml định  nghĩa các dạng hình học, bao gồm cả colors and gradients. Ví dụ, bạn có thể sử dụng shape drawable để thay đổi shape, border, and gradient của một Button hoặc Background.

Solid Color Shapes

Dưới đây là một ví dụ về cách vẽ một hình chữ nhật có viền làm tròn trong res/layout/drawable/ solid_color_shape.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="4dp" />
    <stroke android:width="4dp" android:color="#C1E1A6" /> 
    <solid android:color="#118C4E"/> 
    <padding android:left="20dp" android:top="20dp" 
             android:right="20dp" android:bottom="20dp" /> 
</shape>

Ta sẽ được kết quả như sau:

drawable-android

Gradient Colored Shapes

Shapes cũng hỗ trợ gradients backgrounds đầy đủ các thuộc tính như startColor, centerColor, endColor, angle. Để tạo các gradients như radial, linear or sweep bằng cách sử dụng type property.

Dưới đây là một ví dụ về một hình gradient  đơn giản tại res / layout / drawable / gradient_shape.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="4dp" />
    <stroke android:width="1dp" android:color="#0078a5" /> 
    <gradient
        android:startColor="#0078a5" android:endColor="#00adee" 
        android:angle="90"/>
    <padding android:left="8dp" android:top="2dp" 
             android:right="8dp" android:bottom="2dp" /> 
</shape>

Dưới đây là kết quả:

Gradient Shape

StateListDrawable

Đọc qua tên thì chúng ta cũng hình dung ra rằng Drawable này dùng để mô tả những state (normal, focus, press, disable…) của view. Đúng vậy, drawable này dùng để vẽ những state trên. Và thường xuyên sử dụng cho button, và các item trên ListView hay RecyclerView.

Hình ảnh dưới đây mô tả những state của Button.

drawable-android-5

Để tạo StateListDrawable cũng hoàn toàn tương tự như ShapeDrawable. Tôi tiến hành tạo drawable trong thư mục drawable có tên là button_selector.xml với nội dung như sau:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false" >
        <color android:color="#3498db"/>
    </item>
        <item android:state_pressed="true">
            <color android:color="#2980b9"/>
        </item>
</selector>

Sử dụng drawable cho button

<Button
    android:background="@drawable/button_selector"
    android:text="Save Change"
    android:textColor="@android:color/white"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Các bạn hãy làm thử và xem kết quả.

Bây tôi muốn làm một button như dưới đây:

drawable_android-6

Tôi sẽ có các file như sau:

button_state_normal.xml định nghĩa trạng trái normal của button

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="30dp" />
    <padding
        android:bottom="5dp"
        android:left="10dp"
        android:right="10dp"
        android:top="5dp" />
    <solid android:color="#1abc9c" />
</shape>

button_state_pressed.xml định nghĩa trạng thái khi button được nhấn.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="30dp" />
    <padding
        android:bottom="5dp"
        android:left="10dp"
        android:right="10dp"
        android:top="5dp" />
    <solid android:color="#16a085" />
</shape>

và file button_selector_save_change.xml định nghĩa selector của button gồm 2 state đó là normal và pressed.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_state_normal" android:state_pressed="false" />
    <item android:drawable="@drawable/button_state_pressed" android:state_pressed="true" />
</selector>

Button sử dụng selector

<Button
    android:text="Save Change"
    android:background="@drawable/selector_button_save_change"
    android:textColor="@android:color/white"
    android:layout_centerInParent="true"
    android:layout_width="200dp"
    android:layout_height="wrap_content" />

Sau đó các bạn thử chạy và run chương trình xem kết quả có sự khác biệt gì không.

Ngoài hai state normal và pressed trong android còn có nhiều state khác nữa.

drawable-android-6

Đa số các view trong Android đều có thể những state này. StateListDrawale khá nhiều nên tôi chỉ giới thiệu từng này. Chi tiết hơn các bạn có thể tìm kiếm ở ĐÂY.

CustomDrawable

Trên trên tôi đã giới thiệu những Drawable được giới thiệu trong Android SDK. Tiếp theo mình sẽ tạo drawable cho riêng mình để giúp các bạn hiểu sâu hơn Drawable trong Android.

Tôi tạo class ArcDrawable kế thừa từ Drawable như sau:

public class ArcDrawable extends Drawable {
    private Paint mPaint;
    private RectF mRect;
 
    public ArcDrawable(int color) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(color);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(10);
    }
 
    @Override
    public void draw(Canvas canvas) {
        if (mRect == null)
            mRect = new RectF();
 
        mRect.left = getBounds().left + mPaint.getStrokeWidth() / 2;
        mRect.top = getBounds().top + mPaint.getStrokeWidth() / 2;
        mRect.right = getBounds().right - mPaint.getStrokeWidth() / 2;
        mRect.bottom = getBounds().bottom - mPaint.getStrokeWidth() - 2;
        canvas.drawArc(mRect, 45, 270, false, mPaint);
    }
 
    @Override
    public void setAlpha(int alpha) {
        if (mPaint != null)
            mPaint.setAlpha(alpha);
    }
 
    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }
 
    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
 
}

Và sử dụng Drawable này như sau:

ImageView imvAvatar = (ImageView)findViewById(R.id.imv_avatar);
        ArcDrawable arcDrawable = new ArcDrawable(Color.parseColor("#16a085"));
        imvAvatar.setImageDrawable(arcDrawable);

Kết quả ta thấy như sau:

drawable-android-9

Và dưới đây là hình ảnh của drawale đã sử dụng trong bài viết từ đầu tới cuối

drawable-android-10

Link Project DrawableDemo trên github.

Kết luận

Trên đây tôi đã giới thiệu cho các bạn về một kiến thức được sử dụng khá nhiều trong Android đó là drawable. Hy vọng với những kiến thức mà tôi truyền đạt trong bài viết này giúp bạn có thể thiết kế UI cho ứng dụng một các đẹp đẽ hơn. Và sâu hơn nữa có thể tạo ra những Drawable của chính bạn để có thể sử dụng. Nếu có bất kì thắc mắc bào vui lòng để lại bình luận ở phía dưới. Tôi sẽ sẵng sàng giải đáp thắc mắc của các bạn.

Bài viết được lấy nguồn từ:
https://guides.codepath.com
http://eitguide.com/

Nguyễn Linh

Chia sẻ để cùng tiến bộ...