You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义CircleTextView右侧被裁剪、文字不居中问题如何解决

问题根因

  • 右侧裁剪:
    1. onMeasure方法中直接对MeasureSpec原始值做大小比较,未解析MeasureSpec携带的实际尺寸和测量模式,导致View宽高计算错误,圆形超出View实际绘制区域被裁剪
    2. 布局XML中CircleTextView标签末尾多了冗余的/>闭合符,导致布局属性解析异常
  • 文字不居中:
    测量出的View不是严格正方形,gravity=center仅让文字在View矩形区域居中,和你自定义绘制的圆形中心不匹配。

修复方案

1. 修正自定义CircleTextView代码

主要修改onMeasure逻辑,正确解析测量尺寸,同时优化绘制逻辑适配多设备:

class CircleTextView(context: Context, attrs: AttributeSet) : AppCompatTextView(context, attrs) {

    private val circlePaint = Paint()
    private val strokePaint = Paint()
    // 描边宽度转dp适配不同屏幕密度
    private val strokeWidth = 10f.dp2px(context)

    private fun initViews(context: Context, attrs: AttributeSet) {
        circlePaint.apply {
            color = Color.parseColor("#041421")
            style = Paint.Style.FILL
            isAntiAlias = true
            isDither = true
        }

        strokePaint.apply {
            color = Color.parseColor("#fe440b")
            style = Paint.Style.FILL
            isAntiAlias = true
            isDither = true
        }
        // 内置居中属性,无需额外在布局配置
        gravity = Gravity.CENTER
    }

    override fun onDraw(canvas: Canvas) {
        // 测量后为正方形,宽高一致
        val diameter = measuredWidth
        val radius = diameter / 2f

        // 绘制外圈描边
        canvas.drawCircle(radius, radius, radius, strokePaint)
        // 绘制内圈背景
        canvas.drawCircle(radius, radius, radius - strokeWidth, circlePaint)
        // 绘制TextView原生文字
        super.onDraw(canvas)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 解析两个方向的实际测量尺寸
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)
        // 取最大值作为正方形边长,确保圆形不会被裁剪
        val dimension = max(widthSize, heightSize)
        // 强制设置为正方形尺寸
        setMeasuredDimension(dimension, dimension)
    }
    
    // 扩展函数:dp转px
    private fun Float.dp2px(context: Context): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, context.resources.displayMetrics)
    }

    init {
        initViews(context, attrs)
    }
}

2. 修正XML布局

删除CircleTextView标签末尾冗余的闭合符:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">

    <com.example.ui.views.CircleTextView
        android:id="@+id/circleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/colorWhite"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3. Activity原有逻辑可直接复用

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_splash)

    circleText.apply {
        text = "II"
        setPadding(50, 50, 50, 50)
    }
}

内容的提问来源于stack exchange,提问作者james04

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:57:02