文章目录
Android ShapeableImageView
概述
ShapeableImageView是material控件之一,继承于ImageView,作用是为了让开发者更方便的ImageView进行变形处理。
依赖库
implementation 'com.google.android.material:material:1.4.0'
基本使用
样式:
- cornerFamily:圆角方式;rounded圆角处理,cut切角处理
- cornerSize:圆角尺寸
- strokeColor:边框颜色
- strokeWidth:边框宽度
不变形
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box" />
圆角样式
<!-- 圆角样式-->
<style name="RoundedStyle">
<!-- 角处理方式-->
<item name="cornerFamily">rounded</item>
<!-- 圆角大小-->
<item name="cornerSize">30dp</item>
</style>
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/RoundedStyle" />
圆形样式
<!-- 圆形样式-->
<style name="CircleStyle">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/CircleStyle" />
添加边框
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:padding="2dp"
android:src="@drawable/box"
app:shapeAppearance="@style/CircleStyle"
app:strokeColor="@color/red"
app:strokeWidth="4dp" />
切角样式
<!-- 切角样式-->
<style name="CutStyle">
<item name="cornerFamily">cut</item>
<item name="cornerSize">20dp</item>
</style>
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/CutStyle" />
菱形样式
<!-- 菱形样式-->
<style name="RhombusStyle">
<item name="cornerFamily">cut</item>
<item name="cornerSize">50%</item>
</style>
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/RhombusStyle" />
叶子样式
<!-- 叶子样式-->
<style name="LeafStyle">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopLeft">50%</item>
<item name="cornerSizeBottomRight">50%</item>
</style>
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/LeafStyle" />
半圆样式
<!-- 半圆样式-->
<style name="SemicircleStyle">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopLeft">50%</item>
<item name="cornerSizeTopRight">50%</item>
</style>
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/SemicircleStyle" />
层叠效果
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:src="@drawable/box"
app:shapeAppearance="@style/SemicircleStyle"
app:shapeAppearanceOverlay="@style/CircleStyle" />
ViewOutlineProvider
ShapeableImageView本质是通过ViewOutlineProvider实现剪裁的。ViewOutlineProvider的效率比传统的Xfermode进行剪裁的方式高很多。
实现圆角效果
//绘制圆角
imageView01.apply {
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(0, 0, view.width, view.height, dp2px(30F))
}
}
clipToOutline = true
}
实现圆形效果
//绘制圆形
imageView02.apply {
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setOval(0, 0, view.width, view.height)
}
}
clipToOutline = true
}
其他形状
imageView03.apply {
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
view.elevation = 10F
val gap = 20F
val path = Path()
path.moveTo(-gap, -gap)
path.lineTo(-gap, view.measuredHeight.toFloat() + gap) //左下点
path.lineTo(
(view.measuredWidth / 2).toFloat(),
(view.measuredHeight + 50).toFloat()
)
path.lineTo(
view.measuredWidth.toFloat() + gap,
view.measuredHeight.toFloat() + gap
)
path.lineTo(view.measuredWidth.toFloat() + gap, -gap) //右上点
path.close()
outline.setConvexPath(path)
view.scaleX = 0.5F
view.scaleY = 0.5F
}
}
}