Question

I have a Dialog with a EditText and a button. This EditText will name the database table I will create so its of the utmost importance it is validated. So i would like to pose 2 questions:

1) This is quite simple, but i couldn't fin it anywhere: what characters can a database table name accept? Can it accept numbers? And can a number be the first character?

2) I've managed to validate the EditText using TextWtacher. Here's the code:

et_name.addTextChangedListener(new TextWatcher() {

public void afterTextChanged(Editable s) {

    String filtered_str = s.toString();

        if (filtered_str.matches(".*[^a-z^0-9].*")) {

        filtered_str = filtered_str.replaceAll("[^a-z^0-9]", "");

        s.clear();

        // s.insert(0, filtered_str);

        Toast.makeText(context,
            "Only lowercase letters and numbers are allowed!",
            Toast.LENGTH_SHORT).show();

    }

}

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {}
});

Currently, if the user inserts any character other than lowercase letters and numbers, the textbox is cleared. If I uncomment s.insert(0, filtered_str); in order to to replace the EditText with the filtered string, my app hangs. And guess what I find in the debug?

ERROR/AndroidRuntime(2454): java.lang.StackOverflowError =D

The question is... how can I replace the s text?

-> s.replace(0, s.toString().length(), filtered_str); (remove s.clear, of course) doesn't seem to work either.

Was it helpful?

Solution 2

After some headbanging, I finally found the solution. Seems s.append(filtered_str) after s.clear() works. Dunno why it hasn't work before.

OTHER TIPS

private TextWatcher listenerTextChangedFiltro = new TextWatcher() {
        public void afterTextChanged(Editable editable) {

                final String textoFiltrado = StaticString.filterTextCustom(String.valueOf(editable.toString().toLowerCase()));
                if (!textoFiltrado.equals(editable.toString().toLowerCase())) {
                    editable.clear();
                    editable.append(textoFiltrado);
                }
         }
};

hey! i'm trying similar thing with forcing the input text to be all lowercase; s.clear() followed by s.append() causes a StackOverflow for me too (or still).

wonder why Android puts us thru' hoops to force conversion to lowercase ?

Since using TextWatcher was crashing for me (rightly so... and i couldn't figure out how to work spans), i looked at TransformationMethod.

1st try was to do an inline TransformationMethod on the EditText with something like this:

et.setTransformationMethod(new TransformationMethod() {

        public void onFocusChanged(View view, CharSequence sourceText, boolean focused, int direction,
                Rect previouslyFocusedRect) {
        }

        public CharSequence getTransformation(CharSequence source, View view) {
            String ret = source.toString().toLowerCase();
            System.out.println(ret);
            return ret;
        }
    });

This caused crash due to IndexArrayOutOfBounds as soon as i typed a single char in the ET... could not figure out why.

So, i checked the code for PasswordTransformation and then ReplacementTransformation -- both seem very complicated and i didn't want to bother with all that ?stuff?.

Then in checked out the SinglelineTransformation subclass which was simple... so i created LowerCaseTransformation as subclass of ReplacementTransformation as follows:

public class LowerCaseReplacement extends ReplacementTransformationMethod {
private static final char[] ORIG = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
        'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
private static final char[] REPS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
        'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
private static LowerCaseReplacement singleton;

@Override
protected char[] getOriginal() {
    return ORIG;
}

@Override
protected char[] getReplacement() {
    return REPS;
}

public static LowerCaseReplacement getInstance() {
    if (singleton == null)
        singleton = new LowerCaseReplacement();
    return singleton;
}

}

and adding this xform to et... as in et.setTransformationMethod(LowerCaseReplacement.getInstnace())...

This works!!

If anyone has a better solution, then please enlighten!

The problem is that when you call the insert method, the text changed method is called again. This results in a vicious circle, thus the stack overflow. You can avoid this by not replacing a string that is properly formatted.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top