I currently am trying to make a project which does not use any libraries. Now, I wanted to use a round image many times I can't just do this:
<CardView>
<ImageView/>
</CardView>
every time. So, I decided to make a custom class for it. This is my 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)
}
}
But, that does not seem to work. This is what I get as a result:
And, this the code I used for it:
<com.sambhav2358.facebookclone.customviews.RoundedImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
I am not even sure whether the code reaches that method or not
PS: Dont mark it as duplicate because I tried every thing here but none of them seem to work. Even that method getRoundedCornerBitmap
is taken from a answer but that won't work.
CodePudding user response:
Can you try below code and refer official link for more details.
<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" />
and add this style in you style.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>
As per your requirement you will add items in the custom style.
CodePudding user response:
First of all, you are not drawing on the view
's canvas, you've to override onDraw
to draw anything on the view
's canvas. And, as you just want to make your image circular from the corners, you don't need PorterDuff
for this. You can just clip a rounded rect from the canvas
and it would be suffice for your use case.
You don't have to manually override each constructor of the AppCompatImageView
, You can use the @JvmOverloads
annotation to override every constructor of the java
class in kotlin
.
Use withStyledAttributes
extension function of core-ktx to access attributeSet
init
block can be used to execute code just after the primary constructor
.
Don't do object allocation inside of onDraw
, reuse expensive objects like paint
and path
as much as possible.
Keeping above points in mind, your class can be changed like this
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)
}
}
Now, it can be used like this
<com.sambhav2358.facebookclone.customviews.RoundedImageView
android:layout_width="200dp"
android:layout_height="200dp"
app:cornerRadius="70dp"
android:src="@drawable/ic_launcher_background"
/>