圆角图像视图带有自定义视图

发布于 2025-01-27 12:56:58 字数 2356 浏览 4 评论 0原文

我目前正在尝试制作一个不使用任何库的项目。现在,我想多次使用一个圆形图像,我

<CardView>
   <ImageView/>
</CardView>

每次都不能这样做。因此,我决定为此做一个自定义课程。这是我的班级:

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"/>

我什至不确定代码是否达到该方法


:不要将其标记为重复工作。即使是该方法getRoundedCornerBitmap也从答案中获取,但这行不通。

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:
enter image description here

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青春如此纠结 2025-02-03 12:56:59

首先,您没有在view的画布上绘制,而是要覆盖on Drawview> view's上绘制任何内容帆布。而且,由于您只想从角落使图像循环,因此您不需要Porterduff。您只需从canvas夹住一个圆形的矩形,这对于您的用例就足够了。

您不必手动覆盖appCompatimageView的每个构造函数,您可以使用@jvmoverloads注释来覆盖java class的每个构造函数在kotlin中。

使用withStyLedAttributes core-ktx的扩展功能访问attributeset

init block可以在主构造。

不要在OnDraw的内部进行对象分配,请尽可能多地使用Paint> Paint>和PATH的昂贵对象。

牢记要点,您的班级

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"
        />

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"
        />
゛清羽墨安 2025-02-03 12:56:59

您可以尝试以下代码并参考官方 link for更多细节。

<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" />

并在您的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>

根据您的要求,您将在自定义样式中添加项目。

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.

蘸点软妹酱 2025-02-03 12:56:59

您可以创建一个可绘制的资源,如下所示,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中。

You can create a Drawable resource as follows, 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>

and then you can use it as follows:

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/rounded_corners"/>

And this will create any ImageView with rounded corners. You can control the radius and everything you need in the rounded_corners.xml
I've created it transparent so you can place any image you wish in the ImageView.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文