Android扩展EditText在画布上绘制超出范围

Android扩展EditText在画布上绘制超出范围,android,android-layout,android-custom-view,Android,Android Layout,Android Custom View,我试图通过扩展并覆盖onDraw函数,在下面的EditText上绘制文本: 正如你所看到的,这个词被切断了,从我在网上看到的,他们除了在画布上画画之外,在画布上什么都不做。从我观察到的情况来看,我认为因为EditText的画布是有限的,这就是它被切断的原因我知道有更好的解决方案而不是覆盖onDraw,但我想知道发生这种情况的原因。有人能解释一下吗?多谢各位 CustomEditText.java: public class CustomEditText extends AppCompatEdi

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

正如你所看到的,这个词被切断了,从我在网上看到的,他们除了在画布上画画之外,在画布上什么都不做。从我观察到的情况来看,我认为因为
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);
    }
}
}
<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" />
attrs.xml

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

XML:

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);
    }
}
}
<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" />

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

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

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


尝试将android:clipChildren=“false”android:clipToPadding=“false”添加到此EditText及其所有父布局请编辑问题并添加“R.styleable.CustomEditText”xml。更新:)将尝试该剪辑,ThankyouHi@Subzero,Thankyou它现在正在显示:)但它似乎与我预期的效果不符,它不算作
EditText
上的视图,因为它不是在内部包装,而是在外部包装,下面的视图(密码)不会调整。它只是重叠:/顺便说一句,标题(位于顶部)也被切断了:(我已经用编程方式更新了图像我已经尝试过添加填充,但它只是推送了提示:(最后一行canvas.drawText(mErrorText,getPaddingLeft(),getHeight(),mErrorTextPaint);这是我尝试过的第一件事,实际上,它显示在下面,但顶部也是一个问题。它更可能是一个补丁,而不是我正在寻找的解决方案的正确修复。顺便感谢你的建议:)最好在视图内部绘制。对于这种使用填充。如果你想在视图外部绘制,那么你需要设置android:clipChildren=“false”和android:clipToPadding=“false"在根布局中。但请注意其他视图不会与您的图片重叠。为此,我将在再次遇到问题时尝试此操作。到目前为止,我刚刚创建了一个自定义视图,其中TextView和EditText为1布局,然后我刚刚创建了一个返回EditText的方法,以防我需要修改EditText本身的某些内容。您是elcome,我认为这也是一个比重写EditText的onDraw更好的解决方案