Path中的drawTextOnPath从错误的坐标或从右侧开始显示文本

时间:2019-04-05 01:24:45

标签: android android-canvas android-view android-custom-view

我正在尝试使用图像和文本绘制自定义视图,所有工作都很好,除了我的文本应该从左到右开始,但它是从右到左,上下颠倒。

我已经使用了该图纸的路径,

我的XML输入如下,

with xml input as follows,
 <re.ui.customView.SideMenu
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:icon="@drawable/ic_cart"
            app:padding="15dp"
            app:text_size="25dp"
            app:text="Vikram Singh works with a1 Technology in  mohali"
            app:text_color="@color/wAuth_headerBottomColor"
            app:icon_background="@color/solid_order"
    />

这是我的自定义视图类,

import android.content.Context
import android.graphics.*
import android.text.TextPaint
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import re.R
import re.util.getBitmapFromDrawable
import re.util.withStyledAttributes

class SideMenu(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
View(context, attrs, defStyleAttr) {

private lateinit var mName: String
private lateinit var mBitmap: Bitmap

private var mSizeName: Int = 0
private var mColorName: Int = 0

private var mPadding: Int = 0
private var mColorIcon: Int = 0

private lateinit var mIconPaint: Paint
private lateinit var mRectPaint: Paint
private lateinit var mTextPaint: TextPaint

private lateinit var mRect: Rect
private lateinit var mPath: Path

constructor(context: Context) : this(context, null, 0)

constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)

init {
    context.withStyledAttributes(attrs, R.styleable.SideMenu) {
        mName = getString(R.styleable.SideMenu_text)!!

        mSizeName = getDimensionPixelSize(R.styleable.SideMenu_text_size, 0)
        mPadding = getDimensionPixelSize(R.styleable.SideMenu_padding, 0)

        mColorName = getColor(R.styleable.SideMenu_text_color, 0)
        mColorIcon = getColor(R.styleable.SideMenu_icon_background, 0)

        val drawableResId = getResourceId(R.styleable.SideMenu_icon, -1);
        mBitmap = context.getBitmapFromDrawable(context, drawableResId)
    }

    initAttributes()
}

private fun initAttributes() {

    mIconPaint = Paint()
    with(mIconPaint)
    {
        isAntiAlias = true
        color = mColorIcon
        style = Paint.Style.FILL
    }

    mRectPaint = Paint()
    with(mRectPaint)
    {
        isAntiAlias = true
        color = mColorName
        style = Paint.Style.FILL
    }

    mTextPaint = TextPaint()
    with(mTextPaint)
    {
        isAntiAlias = true
        textSize = mSizeName.toFloat()
        color = Color.BLACK
        textAlign = Paint.Align.CENTER
    }

    mRect = Rect()
    mPath = Path()
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)

    val heightBitmap = mBitmap.height

    val heightNew = heightBitmap + mPadding * 2 + paddingTop + paddingBottom
    setMeasuredDimension(widthMeasureSpec, heightNew)
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    var xLeftCoorinatePath = (paddingLeft).toFloat()
    var yTopCoorinatePath = (paddingTop).toFloat()

    var xRightCoorinatePath = (xLeftCoorinatePath + mPadding*2 + mBitmap.width).toFloat()
    var yBottomCoorinatePath = (height - paddingBottom).toFloat()

    mPath.moveTo(xLeftCoorinatePath, yTopCoorinatePath)
    mPath.lineTo(xRightCoorinatePath, yTopCoorinatePath)
    mPath.lineTo(xRightCoorinatePath, yBottomCoorinatePath)
    mPath.lineTo(xLeftCoorinatePath, yBottomCoorinatePath)
    mPath.lineTo(xLeftCoorinatePath, yTopCoorinatePath)

    mPath.close()
    canvas.drawPath(mPath, mIconPaint)
    mPath.reset()

    val xLeftCoorinateImage = (paddingLeft + mPadding).toFloat()
    val yTopCoorinateImage = (paddingTop + mPadding).toFloat()

    canvas.drawBitmap(mBitmap, xLeftCoorinateImage, yTopCoorinateImage, mIconPaint)

    xLeftCoorinatePath = xRightCoorinatePath
    xRightCoorinatePath = (width - paddingRight).toFloat()

    mPath.moveTo(xLeftCoorinatePath, yTopCoorinatePath)
    mPath.lineTo(xRightCoorinatePath, yTopCoorinatePath)
    mPath.lineTo(xRightCoorinatePath, yBottomCoorinatePath)
    mPath.lineTo(xLeftCoorinatePath, yBottomCoorinatePath)
    mPath.lineTo(xLeftCoorinatePath, yTopCoorinatePath)
    mPath.close()
    canvas.drawPath(mPath, mRectPaint)

    mRect.left = xLeftCoorinatePath.toInt()
    mRect.right = xRightCoorinatePath.toInt()
    mRect.top = yTopCoorinatePath.toInt()
    mRect.bottom = yBottomCoorinatePath.toInt()

    val txt = TextUtils.ellipsize(mName, mTextPaint, mRect.width().toFloat(), TextUtils.TruncateAt.END)
    val charArray: CharArray = txt.toString().toCharArray()

    val yCenter = ((height - (mTextPaint.descent() + mTextPaint.ascent())) / 2)
    canvas.drawTextOnPath(charArray, 0, charArray.size, mPath, 0f , yCenter, mTextPaint)
}
}

我的原始输出如下: Original Output

上述文件的当前输出如下: My output

1 个答案:

答案 0 :(得分:1)

问题出在您的mTextPaint对齐方式上,

with(mTextPaint)         {             isAntiAlias = true             textSize = mSizeName.toFloat()             颜色= Color.BLACK             textAlign = Paint.Align.LEFT         }