Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@kennydude
Created April 17, 2013 21:35
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save kennydude/5407963 to your computer and use it in GitHub Desktop.
Save kennydude/5407963 to your computer and use it in GitHub Desktop.
Ever wanted a prefix and suffix on your EditText? Yes, well this ExtendedEditText class will do it for you!
package me.kennydude.spending.widgets;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.text.Editable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import me.kennydude.spending.R;
import me.kennydude.spending.Utils;
/**
* This is an extended EditText with a Prefix and Suffix.
*
* As used by "Allowance" on Google Play (v1.1)
*/
public class ExtendedEditText extends EditText {
// Stuff to do with our rendering
TextPaint mTextPaint = new TextPaint();
float mFontHeight;
TagDrawable left;
// The actual suffix
String mSuffix = "";
// These are used to store details obtained from the EditText's rendering process
Rect line0bounds = new Rect();
int mLine0Baseline;
public ExtendedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
left = new TagDrawable();
mFontHeight = getTextSize();
mTextPaint.setColor( getCurrentHintTextColor() );
mTextPaint.setTextSize( mFontHeight );
mTextPaint.setTextAlign(Paint.Align.LEFT);
// Setup the left side
setCompoundDrawablesRelative(left, null, null, null);
}
@Override
public void setTypeface(Typeface typeface){
super.setTypeface(typeface);
if(mTextPaint != null){
// Sometimes TextView itself calls me when i'm naked
mTextPaint.setTypeface(typeface);
}
postInvalidate();
}
public void setPrefix(String s) {
left.setText(s);
setCompoundDrawablesRelative( left, null, null, null );
}
public void setSuffix(String s) {
mSuffix = s;
setCompoundDrawablesRelative( left, null, null, null );
}
@Override
public void onDraw(Canvas c){
mLine0Baseline = getLineBounds(0, line0bounds);
super.onDraw(c);
// Now we can calculate what we need!
int xSuffix = (int)mTextPaint.measureText( left.text + getText().toString() ) + getPaddingLeft();
// We need to draw this like this because
// setting a right drawable doesn't work properly and we want this
// just after the text we are editing (but untouchable)
c.drawText( mSuffix, xSuffix, line0bounds.bottom, mTextPaint );
}
// This is for the prefix.
// It is a drawable for rendering text
public class TagDrawable extends Drawable {
public String text = "";
public void setText(String s){
text = s;
// Tell it we need to be as big as we want to be!
setBounds(0,0,getIntrinsicWidth(),getIntrinsicHeight());
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
// I don't know why this y works here, but it does :)
// (aka if you are from Google/are Jake Wharton and I have done it wrong, please tell me!)
canvas.drawText( text, 0, mLine0Baseline + canvas.getClipBounds().top, mTextPaint );
}
@Override public void setAlpha(int i) {}
@Override public void setColorFilter(ColorFilter colorFilter) {}
@Override public int getOpacity() {return 1;}
@Override public int getIntrinsicHeight (){
return (int)mFontHeight;
}
@Override public int getIntrinsicWidth(){
return (int)mTextPaint.measureText( text );
}
}
}
@blocksector
Copy link

im no expert in java and android, if you have time please have a look of my fork of your extendededittext? i added a feature that get the current Drawables of the element and insert it along side with the prefix drawable thanks..

by the way here's my version: https://gist.github.com/jaygauten/fb3fa390a9d62a36edcf

Copy link

ghost commented Nov 11, 2015

so how do i use it in xml??

@ronaksuchak
Copy link

i converted it to kotlin and setSuffix() does nothing !!

i have tried both versions @jaygauten
can you check that

thank you both of you for your gr8 work

@saket
Copy link

saket commented May 6, 2021

FYI measuring text on every draw call is very expensive and should be avoided. Drawing prefixes as compound drawables is a much better option: https://gist.github.com/alexfu/5996908.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment