带有自定义视图的圆角图像视图
Rounded corner image view with a custom view
我目前正在尝试制作一个不使用任何库的项目。现在,我想多次使用圆形图像我不能只这样做:
<CardView>
<ImageView/>
</CardView>
每次。所以,我决定为它定制一个class。这是我的 class:
class RoundedImageView : AppCompatImageView {
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
init(attributeSet)
}
constructor(context: Context) : super(context) {
init(null);
}
private fun init(attributeSet: AttributeSet?) {
if (attributeSet == null) return
val typedArray: TypedArray =
context.obtainStyledAttributes(attributeSet, R.styleable.RoundedImageView, 0, 0)
try {
val bitmapDrawable : BitmapDrawable? = drawable as? BitmapDrawable
val cornerRadius = typedArray.getDimension(R.styleable.RoundedImageView_cornerRadius,0F)
bitmapDrawable?.bitmap?.let { getRoundedCornerBitmap(it, cornerRadius) }
}finally {
typedArray.recycle()
}
}
private fun getRoundedCornerBitmap(bitmap: Bitmap, pixels: Float) {
val output = Bitmap.createBitmap(
bitmap.width, bitmap
.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(output)
val color = -0xbdbdbe
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
val rectF = RectF(rect)
val roundPx = pixels.toFloat()
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
canvas.drawRoundRect(rectF, roundPx, roundPx, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
setImageBitmap(bitmap)
}
}
但是,这似乎不起作用。这就是我得到的结果:
而且,这是我用于它的代码:
<com.sambhav2358.facebookclone.customviews.RoundedImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
我什至不确定代码是否到达那个方法
PS:不要将其标记为重复,因为我在这里尝试了所有方法,但其中 none 似乎有效。即使那个方法 getRoundedCornerBitmap
是从答案中提取的,但那是行不通的。
你可以尝试下面的代码并参考官方 link 了解更多详情。
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/ivNotificationIcon"
android:layout_width="@dimen/_45sdp"
android:layout_height="@dimen/_45sdp"
android:backgroundTint="#EEF3F7"
android:contentDescription="@string/image_description"
android:scaleType="centerInside"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.CornerSize50Percent"
app:srcCompat="@drawable/slider" />
并将此样式添加到您的样式中。xml/theme。xml
<style name="ShapeAppearanceOverlay.App.CornerSize50Percent" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
<item name="backgroundTint">@android:color/white</item> </style>
根据您的要求,您将添加自定义样式的项目。
首先,您不是在 view
的 canvas 上绘制,您必须覆盖 onDraw
才能在 view
上绘制任何内容canvas。而且,由于您只是想让图像的四角呈圆形,因此不需要 PorterDuff
。您可以从 canvas
中剪下一个圆角矩形,这足以满足您的用例。
您不必手动覆盖AppCompatImageView
的每个构造函数,您可以使用@JvmOverloads
注解覆盖java
class中的每个构造函数kotlin
.
使用core-ktx的withStyledAttributes
扩展函数访问attributeSet
init
块可用于在 primary constructor
.
之后执行代码
不要在 onDraw
内部进行对象分配,尽可能重用像 paint
和 path
这样昂贵的对象。
记住以上几点,你的class可以这样改
class RoundedImageView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
val path = Path()
var cornerRadius: Float = 0f
init {
context.withStyledAttributes(attrs, R.styleable.RoundedImageView) {
cornerRadius = getDimension(R.styleable.RoundedImageView_cornerRadius, 0F)
}
}
override fun onDraw(canvas: Canvas?) {
val corners = floatArrayOf(
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius
)
path.addRoundRect(
0f,
0f,
width.toFloat(),
height.toFloat(),
corners,
Path.Direction.CW
)
canvas?.clipPath(path)
super.onDraw(canvas)
}
}
现在可以这样用了
<com.sambhav2358.facebookclone.customviews.RoundedImageView
android:layout_width="200dp"
android:layout_height="200dp"
app:cornerRadius="70dp"
android:src="@drawable/ic_launcher_background"
/>
您可以创建一个 Drawable 资源,如下所示,rounded_corners.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#00000000"/>
</shape>
然后您可以按如下方式使用它:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rounded_corners"/>
这将创建任何带圆角的 ImageView。您可以在 rounded_corners.xml 中控制半径和您需要的一切
我将其创建为透明的,因此您可以在 ImageView 中放置任何您想要的图像。
我目前正在尝试制作一个不使用任何库的项目。现在,我想多次使用圆形图像我不能只这样做:
<CardView>
<ImageView/>
</CardView>
每次。所以,我决定为它定制一个class。这是我的 class:
class RoundedImageView : AppCompatImageView {
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
init(attributeSet)
}
constructor(context: Context) : super(context) {
init(null);
}
private fun init(attributeSet: AttributeSet?) {
if (attributeSet == null) return
val typedArray: TypedArray =
context.obtainStyledAttributes(attributeSet, R.styleable.RoundedImageView, 0, 0)
try {
val bitmapDrawable : BitmapDrawable? = drawable as? BitmapDrawable
val cornerRadius = typedArray.getDimension(R.styleable.RoundedImageView_cornerRadius,0F)
bitmapDrawable?.bitmap?.let { getRoundedCornerBitmap(it, cornerRadius) }
}finally {
typedArray.recycle()
}
}
private fun getRoundedCornerBitmap(bitmap: Bitmap, pixels: Float) {
val output = Bitmap.createBitmap(
bitmap.width, bitmap
.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(output)
val color = -0xbdbdbe
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
val rectF = RectF(rect)
val roundPx = pixels.toFloat()
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
canvas.drawRoundRect(rectF, roundPx, roundPx, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
setImageBitmap(bitmap)
}
}
但是,这似乎不起作用。这就是我得到的结果:
而且,这是我用于它的代码:
<com.sambhav2358.facebookclone.customviews.RoundedImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
我什至不确定代码是否到达那个方法
PS:不要将其标记为重复,因为我在这里尝试了所有方法,但其中 none 似乎有效。即使那个方法 getRoundedCornerBitmap
是从答案中提取的,但那是行不通的。
你可以尝试下面的代码并参考官方 link 了解更多详情。
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/ivNotificationIcon"
android:layout_width="@dimen/_45sdp"
android:layout_height="@dimen/_45sdp"
android:backgroundTint="#EEF3F7"
android:contentDescription="@string/image_description"
android:scaleType="centerInside"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.CornerSize50Percent"
app:srcCompat="@drawable/slider" />
并将此样式添加到您的样式中。xml/theme。xml
<style name="ShapeAppearanceOverlay.App.CornerSize50Percent" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
<item name="backgroundTint">@android:color/white</item> </style>
根据您的要求,您将添加自定义样式的项目。
首先,您不是在 view
的 canvas 上绘制,您必须覆盖 onDraw
才能在 view
上绘制任何内容canvas。而且,由于您只是想让图像的四角呈圆形,因此不需要 PorterDuff
。您可以从 canvas
中剪下一个圆角矩形,这足以满足您的用例。
您不必手动覆盖AppCompatImageView
的每个构造函数,您可以使用@JvmOverloads
注解覆盖java
class中的每个构造函数kotlin
.
使用core-ktx的withStyledAttributes
扩展函数访问attributeSet
init
块可用于在 primary constructor
.
不要在 onDraw
内部进行对象分配,尽可能重用像 paint
和 path
这样昂贵的对象。
记住以上几点,你的class可以这样改
class RoundedImageView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
val path = Path()
var cornerRadius: Float = 0f
init {
context.withStyledAttributes(attrs, R.styleable.RoundedImageView) {
cornerRadius = getDimension(R.styleable.RoundedImageView_cornerRadius, 0F)
}
}
override fun onDraw(canvas: Canvas?) {
val corners = floatArrayOf(
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius,
cornerRadius
)
path.addRoundRect(
0f,
0f,
width.toFloat(),
height.toFloat(),
corners,
Path.Direction.CW
)
canvas?.clipPath(path)
super.onDraw(canvas)
}
}
现在可以这样用了
<com.sambhav2358.facebookclone.customviews.RoundedImageView
android:layout_width="200dp"
android:layout_height="200dp"
app:cornerRadius="70dp"
android:src="@drawable/ic_launcher_background"
/>
您可以创建一个 Drawable 资源,如下所示,rounded_corners.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#00000000"/>
</shape>
然后您可以按如下方式使用它:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rounded_corners"/>
这将创建任何带圆角的 ImageView。您可以在 rounded_corners.xml 中控制半径和您需要的一切 我将其创建为透明的,因此您可以在 ImageView 中放置任何您想要的图像。