circle imageview
This commit is contained in:
parent
245870b96c
commit
e7bdcef024
|
|
@ -12,7 +12,6 @@ import com.ama.core.architecture.appBase.AppViewsFragment
|
||||||
import com.ama.core.architecture.appBase.OnFragmentBackgroundListener
|
import com.ama.core.architecture.appBase.OnFragmentBackgroundListener
|
||||||
import com.ama.core.architecture.util.setStatusBarDarkFont
|
import com.ama.core.architecture.util.setStatusBarDarkFont
|
||||||
import com.ama.core.common.util.dp
|
import com.ama.core.common.util.dp
|
||||||
import com.gamedog.vididin.databinding.VididinappFeatureHomeFragmentHomeBinding
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlin.getValue
|
import kotlin.getValue
|
||||||
import com.gamedog.vididin.databinding.VididinappFeatureMineFragmentMineBinding as ViewBinding
|
import com.gamedog.vididin.databinding.VididinappFeatureMineFragmentMineBinding as ViewBinding
|
||||||
|
|
|
||||||
|
|
@ -25,18 +25,21 @@
|
||||||
android:id="@+id/ll_account_container"
|
android:id="@+id/ll_account_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="30dp"
|
android:layout_marginTop="80dp"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
<com.ama.core.common.widget.roundedimageview.RoundedImageView
|
|
||||||
|
<com.ama.core.architecture.widget.CircleImageView
|
||||||
android:id="@+id/avatar_view"
|
android:id="@+id/avatar_view"
|
||||||
android:layout_width="100dp"
|
android:layout_width="100dp"
|
||||||
android:layout_height="100dp"
|
android:layout_height="100dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:background="@color/gray3"
|
||||||
android:src="@mipmap/temp"
|
android:src="@mipmap/temp"
|
||||||
tools:ignore="ContentDescription" />
|
app:isCircle="true" />
|
||||||
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
package com.ama.core.architecture.widget
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.*
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
import androidx.annotation.AttrRes
|
||||||
|
import com.ama.core.architecture.R
|
||||||
|
import androidx.core.content.withStyledAttributes
|
||||||
|
import androidx.core.graphics.withSave
|
||||||
|
|
||||||
|
class CircleImageView @JvmOverloads constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null,
|
||||||
|
@AttrRes defStyleAttr: Int = 0
|
||||||
|
) : View(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
|
private var bitmap: Bitmap? = null
|
||||||
|
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
|
isAntiAlias = true
|
||||||
|
isDither = true
|
||||||
|
}
|
||||||
|
private val drawRect = RectF()
|
||||||
|
private var scaleType = ScaleType.CENTER_CROP
|
||||||
|
private var roundRadius = 0f
|
||||||
|
private var isCircle = false
|
||||||
|
private val path = Path()
|
||||||
|
|
||||||
|
enum class ScaleType {
|
||||||
|
FIT_XY, CENTER, CENTER_CROP, CENTER_INSIDE
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
attrs?.let { initAttributes(it, defStyleAttr) }
|
||||||
|
setWillNotDraw(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAttributes(attrs: AttributeSet, defStyleAttr: Int) {
|
||||||
|
context.withStyledAttributes(
|
||||||
|
attrs, R.styleable.ProtoImageView, defStyleAttr, 0
|
||||||
|
) {
|
||||||
|
|
||||||
|
val srcResource = getResourceId(R.styleable.ProtoImageView_src, 0)
|
||||||
|
if (srcResource != 0) {
|
||||||
|
setImageResource(srcResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
val scaleTypeIndex = getInt(R.styleable.ProtoImageView_imageScaleType, 2)
|
||||||
|
scaleType = ScaleType.values().getOrElse(scaleTypeIndex) { ScaleType.CENTER_CROP }
|
||||||
|
roundRadius = getDimension(R.styleable.ProtoImageView_roundRadius, 0f)
|
||||||
|
isCircle = getBoolean(R.styleable.ProtoImageView_isCircle, false)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
val width = getMeasuredSize(widthMeasureSpec, true)
|
||||||
|
val height = getMeasuredSize(heightMeasureSpec, false)
|
||||||
|
setMeasuredDimension(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMeasuredSize(measureSpec: Int, isWidth: Boolean): Int {
|
||||||
|
val mode = MeasureSpec.getMode(measureSpec)
|
||||||
|
val size = MeasureSpec.getSize(measureSpec)
|
||||||
|
val intrinsicSize = if (isWidth) {
|
||||||
|
bitmap?.width ?: 0
|
||||||
|
} else {
|
||||||
|
bitmap?.height ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (mode) {
|
||||||
|
MeasureSpec.EXACTLY -> 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<declare-styleable name="ProtoImageView" tools:ignore="ResourceName">
|
||||||
|
<attr name="src" format="reference" />
|
||||||
|
<attr name="imageScaleType">
|
||||||
|
<enum name="fitXY" value="0" />
|
||||||
|
<enum name="center" value="1" />
|
||||||
|
<enum name="centerCrop" value="2" />
|
||||||
|
<enum name="centerInside" value="3" />
|
||||||
|
</attr>
|
||||||
|
<attr name="roundRadius" format="dimension" />
|
||||||
|
<attr name="isCircle" format="boolean" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
||||||
Loading…
Reference in New Issue