From e7bdcef024297799d9e1b80d60f9a3251524a071 Mon Sep 17 00:00:00 2001 From: renhaoting <370797079@qq.com> Date: Fri, 21 Nov 2025 10:47:44 +0800 Subject: [PATCH] circle imageview --- .../vididin/main/fragments/MineFragment.kt | 1 - .../vididinapp_feature_mine_fragment_mine.xml | 9 +- .../architecture/widget/CircleImageView.kt | 187 ++++++++++++++++++ .../src/main/res/values/attrs.xml | 16 ++ 4 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 core/architecture/src/main/java/com/ama/core/architecture/widget/CircleImageView.kt create mode 100644 core/architecture/src/main/res/values/attrs.xml diff --git a/app/src/main/java/com/gamedog/vididin/main/fragments/MineFragment.kt b/app/src/main/java/com/gamedog/vididin/main/fragments/MineFragment.kt index 8e58002..0caf7d5 100644 --- a/app/src/main/java/com/gamedog/vididin/main/fragments/MineFragment.kt +++ b/app/src/main/java/com/gamedog/vididin/main/fragments/MineFragment.kt @@ -12,7 +12,6 @@ import com.ama.core.architecture.appBase.AppViewsFragment import com.ama.core.architecture.appBase.OnFragmentBackgroundListener import com.ama.core.architecture.util.setStatusBarDarkFont import com.ama.core.common.util.dp -import com.gamedog.vididin.databinding.VididinappFeatureHomeFragmentHomeBinding import dagger.hilt.android.AndroidEntryPoint import kotlin.getValue import com.gamedog.vididin.databinding.VididinappFeatureMineFragmentMineBinding as ViewBinding diff --git a/app/src/main/res/layout/vididinapp_feature_mine_fragment_mine.xml b/app/src/main/res/layout/vididinapp_feature_mine_fragment_mine.xml index 411bec7..8c1ac88 100644 --- a/app/src/main/res/layout/vididinapp_feature_mine_fragment_mine.xml +++ b/app/src/main/res/layout/vididinapp_feature_mine_fragment_mine.xml @@ -25,18 +25,21 @@ android:id="@+id/ll_account_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="30dp" + android:layout_marginTop="80dp" android:gravity="center_horizontal" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" android:orientation="vertical"> - + app:isCircle="true" /> size + MeasureSpec.AT_MOST -> if (intrinsicSize > size) size else intrinsicSize + else -> intrinsicSize + } + } + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + updateDrawRect() + updatePath() + } + + private fun updateDrawRect() { + val bitmap = this.bitmap ?: return + val viewWidth = width - paddingLeft - paddingRight + val viewHeight = height - paddingTop - paddingBottom + + drawRect.set(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat()) + + when (scaleType) { + ScaleType.FIT_XY -> { + // 默认使用drawRect的完整区域 + } + ScaleType.CENTER -> { + val left = (viewWidth - bitmap.width) / 2f + val top = (viewHeight - bitmap.height) / 2f + drawRect.set(left, top, left + bitmap.width, top + bitmap.height) + } + ScaleType.CENTER_CROP -> { + val scale = Math.max( + viewWidth / bitmap.width.toFloat(), + viewHeight / bitmap.height.toFloat() + ) + val scaledWidth = bitmap.width * scale + val scaledHeight = bitmap.height * scale + val left = (viewWidth - scaledWidth) / 2 + val top = (viewHeight - scaledHeight) / 2 + drawRect.set(left, top, left + scaledWidth, top + scaledHeight) + } + ScaleType.CENTER_INSIDE -> { + val scale = Math.min( + viewWidth / bitmap.width.toFloat(), + viewHeight / bitmap.height.toFloat() + ).coerceAtMost(1f) + val scaledWidth = bitmap.width * scale + val scaledHeight = bitmap.height * scale + val left = (viewWidth - scaledWidth) / 2 + val top = (viewHeight - scaledHeight) / 2 + drawRect.set(left, top, left + scaledWidth, top + scaledHeight) + } + } + } + + private fun updatePath() { + path.reset() + when { + isCircle -> { + val radius = Math.min(width, height) / 2f + path.addCircle(width / 2f, height / 2f, radius, Path.Direction.CW) + } + roundRadius > 0 -> { + path.addRoundRect( + RectF(0f, 0f, width.toFloat(), height.toFloat()), + roundRadius, roundRadius, Path.Direction.CW + ) + } + else -> { + path.addRect(0f, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW) + } + } + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + val bitmap = this.bitmap ?: return + + canvas.withSave { + if (isCircle || roundRadius > 0) { + clipPath(path) + } + drawBitmap(bitmap, null, drawRect, paint) + } + } + + fun setImageResource(resId: Int) { + bitmap = BitmapFactory.decodeResource(resources, resId) + updateDrawRect() + updatePath() + invalidate() + } + + fun setImageBitmap(bm: Bitmap) { + bitmap = bm + updateDrawRect() + updatePath() + invalidate() + } + + fun setScaleType(scaleType: ScaleType) { + this.scaleType = scaleType + updateDrawRect() + invalidate() + } + + fun setRoundRadius(radius: Float) { + this.roundRadius = radius + updatePath() + invalidate() + } + + fun setCircle(circle: Boolean) { + this.isCircle = circle + updatePath() + invalidate() + } +} \ No newline at end of file diff --git a/core/architecture/src/main/res/values/attrs.xml b/core/architecture/src/main/res/values/attrs.xml new file mode 100644 index 0000000..804a087 --- /dev/null +++ b/core/architecture/src/main/res/values/attrs.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file