当文本对齐居中时无法在 Chip 上绘图

2024-01-14

我正在扩展 Chip 类,以便为我的应用程序进行一些绘图lib https://github.com/AbhinavChauhan97/LoaderChip,我的用例更复杂,但为了简单起见,假设我只是画一条对角线

my code

class MyChip (context: Context,attributeSet: AttributeSet) : Chip(context,attributeSet){

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    //just want to draw a diagonal line
    canvas.drawLine(0f,0f,width/1f,height/1f,paint)
  }
 }

xml

<com.abhinav.chouhan.loaderchipdemo.MyChip
    android:layout_width="200dp"
    android:layout_height="50dp"
    android:textAlignment="center"
    android:text="SOME TEXT"/>

当我没有属性时android:textAlignment="center"一切工作正常,但有了这个属性,我们就无法在芯片上绘制任何东西。 我尝试了一切,但无法弄清楚为什么会发生这种情况。

请帮忙


The Chip小部件严格遵守材料设计指南,并且(IMO)不适合更改。我建议你看看其他小部件 - 也许是材质按钮看看是否有其他东西可以满足您的需求。

您引用的属性,文本对齐方式,可用于TextView这是一个类Chip是基于。Chips期望包装内容并且还期望文本与开头对齐。在混合的某个地方,你的过度绘制会丢失。我怀疑类似的东西是否已经过测试,因为它不符合材料指南。

但是,如果您必须使用Chip,这是使用自定义视图执行此操作的一种方法:

class MyChip @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : Chip(context, attrs, defStyleAttr) {

    private val mLinePaint = Paint().apply {
        color = Color.BLUE
        strokeWidth = 10f
    }

    init {
        doOnNextLayout {
            // Turn off center alignment if specified. We will handle centering ourselves.
            if (isTextAlignmentCenter()) {
                textAlignment = View.TEXT_ALIGNMENT_GRAVITY
                // Get the length of all the stuff before the text.
                val lengthBeforeText =
                    if (isChipIconVisible) iconStartPadding + chipIconSize + iconEndPadding else 0f
                val chipCenter = width / 2
                // Chips have only one line, so we can get away with this.
                val textWidth = layout.getLineWidth(0)
                val newTextStartPadding = chipCenter - (textWidth / 2) - lengthBeforeText
                textStartPadding = max(0f, newTextStartPadding)
                textEndPadding = 0f
            }
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //just want to draw a diagonal line
        canvas.drawLine(0f, 0f, width.toFloat(), height.toFloat(), mLinePaint)
    }

    private fun isTextAlignmentCenter() = textAlignment == View.TEXT_ALIGNMENT_CENTER
}

布局示例:

活动_main.xml

    <com.example.myapplication.MyChip
        android:id="@+id/chip"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:text="Some Chip"
        android:textAlignment="center"
        app:chipIcon="@drawable/ic_baseline_cloud_download_24"
        app:chipIconVisible="true"
        app:closeIcon="@drawable/ic_baseline_clear_24"
        app:closeIconVisible="true" />
</LinearLayout>

结果:

我更深入地研究了这个问题。由于某种原因,画布操作例如drawLine(), drawRect()等不起作用。但是,我可以在画布上绘制文本并用油漆或颜色填充它。


Update:所以,我将问题追溯到bringTextIntoView()的方法TextView。由于我不清楚的原因,视图在正方向上滚动了很多地方(很大,比如成千上万)。正是在这个滚动位置写入文本。来绘制Chip,我们也必须滚动到这个位置。此卷轴解释了为什么我可以用颜色填充画布,但无法在其上绘图以使其可见。

下面将捕获“坏”滚动位置并在绘制之前滚动到该位置Chip。屏幕截图看起来与上图相同。

MyChip.kt

class MyChip @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : Chip(context, attrs, defStyleAttr)/*, View.OnScrollChangeListener*/ {

    private val mLinePaint = Paint().apply {
        color = Color.BLUE
        strokeWidth = 10f
    }

    private var mBadScroll = 0f

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //just want to draw a diagonal line
        canvas.withTranslation(x = mBadScroll) {
            canvas.drawLine(0f, 0f, [email protected] /cdn-cgi/l/email-protection(), height.toFloat(), mLinePaint)
        }
    }

    private fun isTextAlignmentCenter() = textAlignment == View.TEXT_ALIGNMENT_CENTER

    override fun scrollTo(x: Int, y: Int) {
        super.scrollTo(x, y)
        if (isTextAlignmentCenter()) {
            mBadScroll = scrollX.toFloat()
        }
    }
}

Update:水平滚动仍然是问题。在onMeasure()的方法TextView,所需的宽度设置为VERY_WIDE是否为视图启用了水平滚动。 (而且这是为了Chip.) VERY_WIDE是 1024*1024 或一兆字节。这就是我们稍后看到的大卷轴的来源。这个问题与Chip可以直接复制TextView如果我们打电话setHorizontallyScrolling(true) in the TextView.

Chips只有一行,可能不应该滚动。呼唤setHorizontallyScrolling(true)不使Chip or TextView无论如何都可以滚动。上面的代码现在就变成了:

MyChip.kt

class MyChip @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : Chip(context, attrs, defStyleAttr) {

    private val mLinePaint = Paint().apply {
        color = Color.BLUE
        strokeWidth = 10f
    }

    init {
        setHorizontallyScrolling(false)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //just want to draw a diagonal line
        canvas.drawLine(0f, 0f, thi[email protected] /cdn-cgi/l/email-protection(), height.toFloat(), mLinePaint)
    }
}

水平滚动在构造函数中设置为“true”Chip.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当文本对齐居中时无法在 Chip 上绘图 的相关文章

随机推荐