I'm trying to write code for an editText which can accept imperial values { ie. 1 , 3/4 , 1 1/3}. So far, with a lot of help from StackOverflow, I have it just about nailed. But there are three things missing.
android:inputType="number" or numberSigned, numberDecimal, phone etc
none of these display the / key I need to enter data and the QWERTY keyboard is too cumbersome for a single keypress. I'm amazed there isn't a keyboard for this, what do the yanks do? Can I override and replace a single key on the stock keyboard, do I have to implement my own keyboard for this seemingly simple task?
I am also struggling with the logic which prevents the first character being a space or /. I can allow one of each in a given string no problem, I just can't prevent it being the first key. Additionally, when you enter a value - like "1 5/9" - if you backspace to the /, the flags are not reset, so you are prohibited from entering another /.
Code for the InputFilter is as follows:
imperial_filter = new InputFilter() {
boolean canEnterSpace = true, canEnterSlash = true;
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (imperial_editText.getText().toString().equals("")) {
canEnterSpace = true;
canEnterSlash = true;
}
StringBuilder builder = new StringBuilder();
for (int i = start; i < end; i++) {
char currentChar = source.charAt(i);
if (Character.isDigit(currentChar) || (Character.isWhitespace(currentChar) && canEnterSpace && canEnterSlash) || (currentChar == '/' && canEnterSlash)) {
builder.append(currentChar);
if (Character.isWhitespace(currentChar)) canEnterSpace = false;
if (currentChar == '/') canEnterSlash = false;
}
}
return builder.toString();
}
};
And this one is a little more complex, slightly adapted from code already on StackOverflow:
public float testImperialString(String testString) {
boolean goodInput = true, goodInputSpace = true, containsSpace = false;
float result = 0, whole = 0;
String fractions = "";
if (testString.contains(" ")) {
containsSpace = true;
String pieces[] = testString.split(" ");
try {
whole = Float.parseFloat(pieces[0]);
fractions = pieces[1];
} catch (Exception e) {
goodInputSpace = false;
}
} else fractions = testString;
if (fractions.contains("/")) {
//possible division
String pieces[] = fractions.split("/");
if (pieces.length != 2) {
goodInput = false;
} else {
try {
float numerator = Float.parseFloat(pieces[0]);
float denominator = Float.parseFloat(pieces[1]);
result = numerator / denominator;
} catch (Exception e) {
goodInput = false;
}
}
}
if (!testString.contains(" ") && !(result > 0)) {
try {
result = Float.parseFloat(testString);
} catch (Exception e) {
goodInput = false;
}
}
Log.d(TAG, "Contains Space = " + containsSpace + " Good Input = " + goodInput + " Good InputSpace = " + goodInputSpace);
return whole + result;
}
I run that result through a method which converts imperial measurements into a metric equivalent, that I can perform maths functions with.
TL:DR
- I need a number keyboard with a / symbol
- I need to prevent a space or / as the first letter of an input
- I need to re-allow a space or / input, if a previous occurrence in a string was deleted.