i created a layout for one of my activities in which users can insert a value in some EditText widget. I need that some of these EditText must have a suffix (like cm, mm and so on) that has to be not editable. After the user has inserted the value i will parse the content of these EditText avoiding the suffix so i will handle the only input without the suffix. How to do that?
I have already searched and searched here on SO but nothing helped me. I found answers like this one https://stackoverflow.com/a/20794581/2516399 that don't help me.
I hope i was clear in my question... sorry for my english
I have made extension function for EditText:
fun EditText.addSuffix(suffix: String) {
val editText = this
val formattedSuffix = " $suffix"
var text = ""
var isSuffixModified = false
val setCursorPosition: () -> Unit =
{ Selection.setSelection(editableText, editableText.length - formattedSuffix.length) }
val setEditText: () -> Unit = {
editText.setText(text)
setCursorPosition()
}
this.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
val newText = editable.toString()
if (isSuffixModified) {
// user tried to modify suffix
isSuffixModified = false
setEditText()
} else if (text.isNotEmpty() && newText.length < text.length && !newText.contains(formattedSuffix)) {
// user tried to delete suffix
setEditText()
} else if (!newText.contains(formattedSuffix)) {
// new input, add suffix
text = "$newText$formattedSuffix"
setEditText()
} else {
text = newText
}
}
override fun beforeTextChanged(charSequence: CharSequence?, start: Int, count: Int, after: Int) {
charSequence?.let {
val textLengthWithoutSuffix = it.length - formattedSuffix.length
if (it.isNotEmpty() && start > textLengthWithoutSuffix) {
isSuffixModified = true
}
}
}
override fun onTextChanged(charSequence: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
You can then use it as:
yourEditTextView.addSuffix("suffix")
This is my solution: An EditText class that draws the suffix behind the text. There are two custom attributes for defining the text of the suffix and the suffix padding (to the left corner of the EditText).
public class EditTextWithSuffix extends EditText {
TextPaint textPaint = new TextPaint();
private String suffix = "";
private float suffixPadding;
public EditTextWithSuffix(Context context) {
super(context);
}
public EditTextWithSuffix(Context context, AttributeSet attrs) {
super(context, attrs);
getAttributes(context, attrs, 0);
}
public EditTextWithSuffix(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
getAttributes(context, attrs, defStyleAttr);
}
@Override
public void onDraw(Canvas c){
super.onDraw(c);
int suffixXPosition = (int) textPaint.measureText(getText().toString()) + getPaddingLeft();
c.drawText(suffix, Math.max(suffixXPosition, suffixPadding), getBaseline(), textPaint);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
textPaint.setColor(getCurrentTextColor());
textPaint.setTextSize(getTextSize());
textPaint.setTextAlign(Paint.Align.LEFT);
}
private void getAttributes(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.EditTextWithSuffix, defStyleAttr, 0);
if(a != null) {
suffix = a.getString(R.styleable.EditTextWithSuffix_suffix);
if(suffix == null) {
suffix = "";
}
suffixPadding = a.getDimension(R.styleable.EditTextWithSuffix_suffixPadding, 0);
}
a.recycle();
}
}
here is the attributes definition:
<resources>
<declare-styleable name="EditTextWithSuffix">
<attr name="suffix" format="string|reference" />
<attr name="suffixPadding" format="dimension" />
</declare-styleable>
</resources>
private static final String mSuffix = "SUFX";
@Override
protected void onCreate(Bundle savedInstanceState) {
final EditText et = new EditText(this);
et.setText(mSuffix);
et.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
//NO FOCUS
if(!hasFocus){
//HAS USER CLEARED THE SUFFIX
if(!et.getText().toString().contains(mSuffix)){
//ADDING SUFFIX AGAIN
String newText = et.getText().toString();
et.setText(mSuffix+newText);
}
}
}
});
}
In my opinion, use Regular Exp. to check the suffix. it will be more secure and simple.
SOLUTION:2
Here is another solution,something tricky ;)
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/test_value"
android:layout_alignParentLeft="true"
android:id="@+id/editText2"
android:layout_gravity="center"
/>
<TextView
android:id="@+id/text_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="@string/hint_test"
android:textSize="18sp"
android:layout_marginRight="10dp"
android:textColor="#808080"
/>
</RelativeLayout>
RESULT/OUTPUT
REF:StackOverFlow
Try this
final EditText eTxt = (EditText) findViewById(R.id.edit_text);
eTxt.setText("cm");
Selection.setSelection(eTxt.getText(), eTxt.getText().length());
eTxt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
if(!s.toString().startsWith("cm")){
eTxt.setText("cm");
Selection.setSelection(eTxt.getText(), eTxt.getText().length());
}
}
});
Try Out the following code for numeric edittext with alphabetic suffix:-
expiry.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence c, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable e) {
String s = e.toString();
if (s.length() > 0) {
if (!s.endsWith("days")) {
if (!s.equals(s + "days")) {
s = s.replaceAll("[^\\d.]", "");
expiry.setText(s + "days");
} else {
expiry.setSelection(s.length() - "days".length());
}
} else {
expiry.setSelection(s.length() - "days".length());
if (s.equals("days")) {
expiry.setText("");
}
}
}
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With