Tenten Ponce
Tenten Ponce

Reputation: 2506

Android extend EditText draw on canvas out of bounds

Im trying to draw text on EditText below by extending it and overriding onDraw function:

enter image description here

As you can see, the word gets cut off, from what am I seeing online, they don't do anything on the canvas aside from drawing on it. From what I've observed, I think because the canvas of the EditText is limited, that's why it is being cut off. I know there's a better solution rather than overriding onDraw, but I want to know the reason why this is happening. Can anybody explain or give a hint? Thank you very much.

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" />

Upvotes: 3

Views: 975

Answers (2)

jfawkes
jfawkes

Reputation: 406

I think you are misinterpreting android canvas coordinate. Origin coordinate (0, 0) of a canvas is at the very left top x-coordinate is increasing as you go to the right and y-coordinate is increasing as you go to the bottom. You need to pass left top coordinate of the text that you want to draw.

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

I could not understand where do you want to draw the the text so assuming that you want to draw at the top left of the view have to call draw text like this

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

Upvotes: 1

UgAr0FF
UgAr0FF

Reputation: 825

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

Upvotes: 0

Related Questions