+7

Hiển thị Image nhiều hình dạng với ShapeableImageView

Trước đây, khi ta sử dụng ImageView để hiển thị hình ảnh thì nó đơn giản chỉ hiển thị với hình chữ nhật cùi mía thôi. Để hiển thị hình dạng khác mà không tốn thời gian custom view thì ta thường nhờ đến sự cứu cánh của các thư viện, điển hình như CircleImageView của hdodenhof.

Và rồi cuối cùng thì Android cũng đã giới thiệu ShapeableImageView trong Material Design.

ShapeableImageView

ShapeableImageView kế thừa từ AppCompatImageView , nghĩa là nó có tất cả các function được cung cấp như trong AppCompatImageView

XML Attributes mới

  • strokeColor: màu đường viền của ImageView
  • strokeWidth: độ rộng đường viền của ImageView
  • cornerFamily: xác định corner của hình với giá trị là cut hoặc rounded tương ứng với loại cắt góc hay bo góc
  • cornerSize: xác định kích thước của corner, có thể sử dụng bằng giá trị phần trăm hoặc dp

Sử dụng

Thêm marerial design vào Gradle

implementation ‘com.google.android.material:material:1.2.0’

Circle ImageView

Circle ImageView thường được sử dụng nhiều cho avatar của user.

Đầu tiên, ta tạo style.

<style name="circle">
    <item name="cornerSize">50%</item>
</style>

Như ở trên, ta không thêm attribute cornerFamily vì giá trị mặc định của nó chính là rounded.

Sau đó gán style vào attribute app:shapeApperanceOverlay ở trong file layout

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/circle"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:scaleType="centerCrop"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:shapeAppearanceOverlay="@style/circle"
    app:srcCompat="@drawable/doge" />

Circle ImageView Border

Ta dùng style như Circle Image trên và thêm thuộc tính strokeColor và strokeWidth để thêm border.

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/circle_border"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:padding="5dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:shapeAppearanceOverlay="@style/circle"
    app:srcCompat="@drawable/doge"
    app:strokeColor="@color/black"
    app:strokeWidth="5dp" />

Rounded Corner Image

Với loại hình bo góc ta cũng có thể thực hiện bằng cách lồng ImageView vào CardView vì CardView có hỗ trợ bo góc, tuy nhiên nó có thể làm giảm hiệu suất khi render layout. Vì vậy dùng ShapeableImageView thay thế là cách tốt hơn

Thêm style

<style name="rounded_corner">
    <item name="cornerSize">20dp</item>
</style>

Sử dụng style trong layout

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/rounded_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:scaleType="centerCrop"
    app:layout_constraintStart_toStartOf="parent"
    app:shapeAppearanceOverlay="@style/rounded_corner"
    app:srcCompat="@drawable/doge" />

Rounded Corner Image Border

Tương tự, ta thêm thuộc tính strokeWidth và strokeColor

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/rounded_corner_with_border"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:padding="5dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:shapeAppearanceOverlay="@style/rounded_corner"
    app:srcCompat="@drawable/doge"
    app:strokeColor="@color/black"
    app:strokeWidth="5dp" />

Cut Corner Image

Đến đây thì ta phải thêm attribute cornerFamily với giá trị là cut

Tạo style

<style name="cut_corner">
    <item name="cornerSize">20dp</item>
    <item name="cornerFamily">cut</item>
</style>

Thêm vào layout

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/cut_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:scaleType="centerCrop"
    app:layout_constraintStart_toStartOf="parent"
    app:shapeAppearanceOverlay="@style/cut_corner"
    app:srcCompat="@drawable/doge" />

Cut Corner Image Border

Tương tự

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/cut_corner_border"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:padding="5dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:shapeAppearanceOverlay="@style/cut_corner"
    app:srcCompat="@drawable/doge"
    app:strokeColor="@color/black"
    app:strokeWidth="5dp" />

Specific Rounded Corner

Thêm style

<style name="specific_rounded_corner">
    <item name="cornerSizeTopLeft">50dp</item>
    <item name="cornerSizeBottomRight">50dp</item>
    <item name="cornerFamilyTopLeft">rounded</item>
    <item name="cornerFamilyBottomRight">rounded</item>
</style>

Thêm vào layout

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/specific_rounded_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:scaleType="centerCrop"
    app:layout_constraintStart_toStartOf="parent"
    app:shapeAppearanceOverlay="@style/specific_rounded_corner"
    app:srcCompat="@drawable/doge" />

Specific Rounded Corner Border

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/specific_rounded_border_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:padding="5dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:shapeAppearanceOverlay="@style/specific_rounded_corner"
    app:srcCompat="@drawable/doge"
    app:strokeColor="@color/black"
    app:strokeWidth="5dp" />

Specific Cut Corner

Thêm style

<style name="specific_cut_corner">
    <item name="cornerSizeTopLeft">50dp</item>
    <item name="cornerSizeBottomRight">50dp</item>
    <item name="cornerFamilyTopLeft">cut</item>
    <item name="cornerFamilyBottomRight">cut</item>
</style>

Thêm vào layout


<com.gogle.android.material.imageview.ShapeableImageView
    android:id="@+id/specific_cut_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:scaleType="centerCrop"
    app:shapeAppearanceOverlay="@style/specific_cut_corner"
    app:srcCompat="@drawable/doge" />

Specific Cut Corner Border

Tương tự

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/specific_cut_border_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:padding="5dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:shapeAppearanceOverlay="@style/specific_cut_corner"
    app:srcCompat="@drawable/doge"
    app:strokeColor="@color/black"
    app:strokeWidth="5dp" />

ImageView Rounded and Cut Corners

Một số design sẽ có cả sự kết hợp giữa bo góc và căn góc.

Thêm style

<style name="specific_mix_corner">
    <item name="cornerSize">50dp</item>
    <item name="cornerFamilyTopLeft">cut</item>
    <item name="cornerFamilyBottomRight">cut</item>
    <item name="cornerFamilyBottomLeft">rounded</item>
    <item name="cornerFamilyTopRight">rounded</item>
</style>

Thêm vào layout

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/specific_mix_corner"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp"
    android:scaleType="centerCrop"
    app:shapeAppearanceOverlay="@style/specific_mix_corner"
    app:srcCompat="@drawable/doge" />

Programmatically với Kotlin

Nếu muốn set qua code thì ShapeableImageView cung cấp một số hàm mà ta có thể sử dụng.

Ví dụ ta muốn set Top Right Corner bo góc với size là 14dp:

topCornerImage.setShapeAppearanceModel(topCornerImage.getShapeAppearanceModel()
        .toBuilder()
        .setTopRightCorner(CornerFamily.ROUNDED,14dp)
        .build());

Nguồn tham khảo

https://amahmoud91.medium.com/deep-dive-into-shapeableimageview-in-android-1ba7f9a5969e


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.