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