Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/206.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在具有中心裁剪的自定义图像视图中生成圆形图像?_Android_Kotlin_Imageview_Android Custom View - Fatal编程技术网

Android 如何在具有中心裁剪的自定义图像视图中生成圆形图像?

Android 如何在具有中心裁剪的自定义图像视图中生成圆形图像?,android,kotlin,imageview,android-custom-view,Android,Kotlin,Imageview,Android Custom View,我想为头像创建自定义图像视图,它可以在两种模式下工作: 如果android:src为空,则显示圆圈中有名称的第一个字母 Else显示圆形化身 现在,如果我使用android:src我的drawable不在中心,我如何才能使它成为中心裁剪 以下是自定义视图的代码: class AvatarImageView : AppCompatImageView{ private var letter = "" private var avatarBackgroundColor = 0

我想为头像创建自定义图像视图,它可以在两种模式下工作:

  • 如果android:src为空,则显示圆圈中有名称的第一个字母
  • Else显示圆形化身
  • 现在,如果我使用android:src我的drawable不在中心,我如何才能使它成为中心裁剪

    以下是自定义视图的代码:

    class AvatarImageView : AppCompatImageView{
    
        private var letter = ""
        private var avatarBackgroundColor = 0
        private var avatarLetterColor = 0
    
        private val paintBackground = Paint()
        private val paintLetter = Paint(Paint.LINEAR_TEXT_FLAG)
        private val paintAvatarImage = Paint()
    
        private var circleX = 0f
        private var circleY = 0f
        private var circleRadius = 0f
    
        private var letterX = 0f
        private var letterY = 0f
    
        private val avatarImageRect = RectF(0f, 0f, 0f, 0f)
    
        constructor(context : Context)
                : this(context, null)
    
        constructor(context: Context, attrs : AttributeSet?)
                : this(context, attrs, 0)
    
        constructor(context: Context, attrs : AttributeSet?, defStyleAttr : Int)
                : super(context, attrs, defStyleAttr){
            attrs?.let{
                val array = context.obtainStyledAttributes(it, R.styleable.AvatarImageView)
                letter = array.getString(R.styleable.AvatarImageView_signature)?.trim()?.substring(0..0)?.toUpperCase(Locale.ROOT) ?: ""
                avatarBackgroundColor = array.getColor(R.styleable.AvatarImageView_background_color, Color.BLUE)
                avatarLetterColor = array.getColor(R.styleable.AvatarImageView_letter_color, Color.WHITE)
                array.recycle()
            }
            init()
        }
    
        private fun init(){
            paintBackground.style = Paint.Style.FILL
            paintBackground.color = avatarBackgroundColor
    
            paintLetter.color = avatarLetterColor
            paintLetter.textAlign = Paint.Align.CENTER
            paintLetter.isAntiAlias = true
            paintLetter.style = Paint.Style.FILL
    
            drawable?.let{
                paintAvatarImage.isAntiAlias = true
                val shader = BitmapShader(getBitmapFromDrawable(it), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
                paintAvatarImage.shader = shader
            }
        }
    
        private fun getBitmapFromDrawable(drawable: Drawable): Bitmap{
            if (drawable is BitmapDrawable) {
                drawable.bitmap?.let {
                    return drawable.bitmap
                }
            }
    
            val bitmap: Bitmap = Bitmap.createBitmap(
                drawable.intrinsicWidth,
                drawable.intrinsicHeight,
                Bitmap.Config.ARGB_8888
            )
            return bitmap
        }
    
        override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
            super.onLayout(changed, left, top, right, bottom)
    
            val availableWidth = width
            val availableHeight = height
    
            circleX = availableWidth / 2f
            circleY = availableHeight / 2f
            circleRadius = min(availableWidth, availableHeight) / 2f
    
            paintLetter.textSize = availableHeight / 2f
            letterX = availableWidth / 2f
            letterY = availableHeight / 2f - ((paintLetter.descent() + paintLetter.ascent()) / 2f)
    
            avatarImageRect.right = width.toFloat()
            avatarImageRect.bottom = height.toFloat()
        }
    
        override fun onDraw(canvas: Canvas?) {
            drawable?.let{
                canvas?.drawRoundRect(avatarImageRect, width.toFloat(), height.toFloat(), paintAvatarImage)
            } ?:run {
                canvas?.drawCircle(circleX, circleY, circleRadius, paintBackground)
                canvas?.drawText(letter, letterX, letterY, paintLetter)
            }
        }
    }
    
    我的xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:padding="16dp"
        tools:context=".ui.AvatarsFragment">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <com.test.test.views.AvatarImageView
                android:layout_width="32dp"
                android:layout_height="32dp"
                android:src="@drawable/avatar"/>
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginStart="10dp"
                style="@style/TextAppearance.AppCompat.Medium"
                android:text="Ivan Ivanov"/>
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="10dp">
    
            <com.test.test.views.AvatarImageView
                android:layout_width="32dp"
                android:layout_height="32dp"
                app:signature="Ivan Ivanov"/>
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginStart="10dp"
                style="@style/TextAppearance.AppCompat.Medium"
                android:text="Ivan Ivanov"/>
    
        </LinearLayout>
    
    </LinearLayout>
    
    
    

    更新:我知道其他库,但我不想使用它们。

    我使用CircleImageView显示图像,毕加索将图像加载到CircleImageView 毕加索将图像居中并裁剪 它对我有用…

    解决了: 我现在使用此代码从以下位置裁剪图像:


    遵循此循环图像视图,我想在没有图书馆的情况下进行此操作这仍然是一个很好的起点。。。该库的代码如下:(您可以提取循环裁剪的相关部分)。
    private fun getCircleBitmap(bitmap: Bitmap): Bitmap {
            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)
    
            paint.isAntiAlias = true
            canvas.drawARGB(0, 0, 0, 0)
            paint.color = color
    
            canvas.drawCircle(
                bitmap.width / 2f, bitmap.height / 2f,
                bitmap.width / 2f, paint
            )
            paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
            canvas.drawBitmap(bitmap, rect, rect, paint)
    
            return output
        }