Android扩展了EditText在画布上绘制的边界

时间:2018-07-20 10:00:40

标签: android android-layout android-custom-view

我正在尝试通过扩展文本并覆盖EditText函数在下面的onDraw上绘制文本:

enter image description here

正如您所看到的,这个词被切断了,从我在网上看到的内容来看,除了在画布上绘画外,他们在画布上什么也没做。从我观察到的结果来看,我认为由于EditText的画布是有限的,所以才将其切掉。 我知道有一个更好的解决方案,而不是覆盖onDraw,但我想知道为什么会这样。有人可以解释或提示吗?非常感谢。

CustomEditText.java:

public class CustomEditText extends AppCompatEditText {

private Rect mTitleRect;
private Rect mErrorTextRect;

private Paint mTitlePaint;
private Paint mErrorTextPaint;

private String mTitle = "";
private String mErrorText = "";

private int mEditTextHeight;

public CustomEditText(Context context) {
    super(context);
}

public CustomEditText(Context context, AttributeSet attrs) {
    super(context, attrs, R.attr.customEditTextStyle);
    init();
    init(context, attrs);
}

public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
    init(context, attrs);
}

private void init() {
    mTitleRect = new Rect();
    mErrorTextRect = new Rect();

    mTitlePaint = new Paint();
    mErrorTextPaint = new Paint();

    mTitlePaint.setColor(Color.BLACK);
    mTitlePaint.setTextSize(getResources().getDimension(R.dimen.text_small));

    mErrorTextPaint.setColor(Color.parseColor("#FF4336"));
    mErrorTextPaint.setTextSize(getResources().getDimension(R.dimen.text_small));
}

private void init(Context context, AttributeSet attrs) {
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText);

    try {
        mTitle = a.getString(R.styleable.CustomEditText_headerTitle);
        mErrorText = a.getString(R.styleable.CustomEditText_errorText);
    } finally {
        a.recycle();
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mEditTextHeight = h;

    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mTitle != null && !mTitle.isEmpty()) {
        mTitlePaint.getTextBounds(mTitle, 0, mTitle.length(), mTitleRect);
        canvas.drawText(mTitle, getPaddingLeft(), getPaddingTop() - mTitleRect.height(), mTitlePaint);
    }

    if (mErrorText != null && !mErrorText.isEmpty()) {
        mErrorTextPaint.getTextBounds(mErrorText, 0, mErrorText.length(), mErrorTextRect);
        canvas.drawText(mErrorText, getPaddingLeft(), mEditTextHeight + mErrorTextRect.height() / 2, mErrorTextPaint);
    }
}
}

attrs.xml

<declare-styleable name="CustomEditText">
    <attr name="errorText" format="string|reference" />
    <attr name="headerTitle" format="string|reference" />
</declare-styleable>

XML:

<com.mypackage.CustomEditText
                android:id="@+id/et_username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Username"
                app:errorText="errorrrr"
                app:headerTitle="testing title" />

2 个答案:

答案 0 :(得分:1)

我认为您误解了 android 画布坐标。画布的原点坐标 (0, 0) 位于最左上角,向右移动时 x 坐标增加,向下移动时 y 坐标增加。 您需要传递要绘制的文本的左上坐标。

https://developer.android.com/reference/android/graphics/Canvas#drawText(java.lang.String,%20float,%20float,%20android.graphics.Paint)

我不明白你想在哪里绘制文本,所以假设你想在视图的左上角绘制必须像这样调用绘制文本

canvas.drawText(mTitle, getPaddingLeft(), getPaddingTop(), mTitlePaint);

答案 1 :(得分:0)

public class CustomEditText extends AppCompatEditText {

private Rect mTitleRect;
private Rect mErrorTextRect;

private Paint mTitlePaint;
private Paint mErrorTextPaint;

private String mTitle = "";
private String mErrorText = "";

private int mEditTextHeight;

public CustomEditText(Context context) {
    this(context, null);
}

public CustomEditText(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
    init(attrs);
}

private void init() {
    mTitleRect = new Rect();
    mErrorTextRect = new Rect();

    mTitlePaint = new Paint();
    mErrorTextPaint = new Paint();

    mTitlePaint.setColor(Color.BLACK);
    mTitlePaint.setTextSize(getResources().getDimension(R.dimen.text_small));

    mErrorTextPaint.setColor(Color.parseColor("#FF4336"));
    mErrorTextPaint.setTextSize(getResources().getDimension(R.dimen.text_small));
}

private void init(AttributeSet attrs) {
    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CustomEditText);

    try {
        mTitle = a.getString(R.styleable.CustomEditText_headerTitle);
        mErrorText = a.getString(R.styleable.CustomEditText_errorText);
    } finally {
        a.recycle();
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mEditTextHeight = h;

    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    setPadding(0, 0, 0, (int) getResources().getDimension(R.dimen.text_small));

    if (mTitle != null && !mTitle.isEmpty()) {
        mTitlePaint.getTextBounds(mTitle, 0, mTitle.length(), mTitleRect);
        canvas.drawText(mTitle, getPaddingLeft(), getPaddingTop() - mTitleRect.height(), mTitlePaint);
    }

    if (mErrorText != null && !mErrorText.isEmpty()) {
        mErrorTextPaint.getTextBounds(mErrorText, 0, mErrorText.length(), mErrorTextRect);
        canvas.drawText(mErrorText, getPaddingLeft(), getHeight(), mErrorTextPaint);
    }
}