Well, that's what i think could be a way to do it:
- Get the
EditText
width
- Get the text width
Before anything, the code here is not perfect and it allows the user to put a bit more than the width (maybe due to the fact that EditText.getWidth()
will return the value with borders etc.) It's just to give an idea.
More problems about this approch is the fact that even if we don't show the text inside the EditText the keyboard buffer will still know about that and it will create a bad effect for the user, i tried to use InputFilter
but the result is the same (well, it was more buggy).
private int widthEditText;
// [...] in onCreate:
final EditText editText = (EditText) findViewById(R.id.text);
// p.s in onCreate the layout is not created yet, so i should wait to read the width
editText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
widthEditText = editText.getWidth();
}
});
editText.addTextChangedListener(new TextWatcher() {
private String previousText;
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Paint paint = editText.getPaint();
Rect rectangle = new Rect();
/* i used getTextBounds instead of measureText because it will return the float value but getWidth of
* edit text is a int. */
paint.getTextBounds(editable.toString(), 0, editable.length(), rectangle);
Log.d(TAG, "Text width: " + rectangle.width());
if (rectangle.width() > widthEditText) {
/* the user cannot type anymore */
Log.d(TAG, widthEditText + " > " + rectangle.width() + " blocked.");
editable.replace(0, editable.length(), previousText);
return;
}
previousText = editable.toString();
Log.d(TAG, "Continue to write, new previousText: " + previousText);
}
});
Just to see, i tried to use measureText
which returns the width in float (and work with comparing int and float) with the same result:
@Override
public void afterTextChanged(Editable editable) {
Paint paint = editText.getPaint();
// Rect rectangle = new Rect();
/* i used getTextBounds instead of measureText because it will return the float value but getWidth of
* edit text is a int. */
// paint.getTextBounds(editable.toString(), 0, editable.length(), rectangle);
float width = paint.measureText(editable.toString());
Log.d(TAG, "Text width: " + width);
if (width > widthEditText) {
/* the user cannot type anymore */
Log.d(TAG, widthEditText + " > " + width + " blocked.");
editable.replace(0, editable.length(), previousText);
return;
}
previousText = editable.toString();
Log.d(TAG, "Continue to write, new previousText: " + previousText);
}
The result is pretty the same...
I played around with android:ems="4"
which should provide the font size (maybe something could be done to make it fit better?) but nothing (well not, seems like something it looks better but i feel it totally random based on the words).
Personally, i would avoid this since for me it sounds a bit random... maybe exists a better approch which i didn't know..
i tested it with a Samsung S4 device, so i don't know if it works with other devices! Sorry about that, but Genymotion don't works