Concept Questions - Textbox with selective input - java

I've got a bit of a concept question I'd like to have answered.
I'm aiming to make an android application in which textboxes can only have specific types of inputs. As an example, decimal numbers are easy, you use a Number text box. However, if I were to use hexidecimal numbering system as an example, how can I have my box reject any input that is attempted to be entered that is not a valid hexidecimal character (0-F)? This concept could be extended to the octal and binary numbering systems. Ideally, the keyboard which appears when the box is clicked would only display valid characters for that particular box, but I'm not sure if that is possible.
Thanks!
K.

Overwrite the textbox listener and on key stroke, get the inputed text, run the conditions you want. If it passes, it is acceptable, if not you warn the user ..
EXAMPLE of listener:
tv = (TextView)findViewById(R.id.charCounts);
textMessage = (EditText)findViewById(R.id.textMessage);
textMessage.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){
//Check if text is hexadecimal
}
});

Look into using a filter
http://developer.android.com/reference/android/widget/Filter.html

Related

Detect and change only "hello" text font-family from editText

I have an editText box and when user writes "hello" I want only change "hello" font-family change to italic but others text font-family stay same only change "hello"
String detectText, text;
detectText = "hello";
text = title.getText().toString();
detectText.
Could you please help me?
As someone said, you need a text watcher to be able to make changes when the text is changed. You also need spans to be able to style parts of the text. Here's a way to do it:
editText.addTextChangedListener(new TextWatcher() {
private static final String KEYWORD = "hello";
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {
// Remove previous spans.
for (StyleSpan span : s.getSpans(0, s.length(), StyleSpan.class)) {
s.removeSpan(span);
}
// Add new spans for every occurrence of the keyword.
int i = 0;
while (i != -1) {
i = text.toString().indexOf(KEYWORD, i);
if (i != -1) {
s.setSpan(new StyleSpan(Typeface.ITALIC), i, i + KEYWORD.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
i += KEYWORD.length();
}
}
}
});
The text watcher has three methods called at different times of the editing, but it's only safe to make changes to the text in afterTextChanged. There, all previous style spans are removed then the text is scanned to add new ones.
Note that performance might be a problem if you intend to turn this into something a lot more complex, like a syntax highlighter. Right now all spans get readded everytime the user changes a single character.

java.lang.IndexOutOfBoundsException: setSpan (118 ... 119) ends beyond length 118

I searched different questions but found nothing specific about my problem. I am changing text color by selecting color and works successfully however when I start deleting my edit text after typing a color text I get this error.
myedittext.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
spannableString.setSpan(new ForegroundColorSpan(Color.parseColor(txtColor)), start, start+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
I get the following error
java.lang.IndexOutOfBoundsException: setSpan (118 ... 119) ends beyond length 118
at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1309)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:680)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:672)
at com.apps.primalnotes.Fragments.EditorFragment$16.onTextChanged(EditorFragment.java:842)
at android.widget.TextView.sendOnTextChanged(TextView.java:10611)
at android.widget.TextView.handleTextChanged(TextView.java:10715)
at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:14057)
I am writing in two colors now like this
now when i save it. it saves in pink color only and shows me like this
but now when i save it again without any changes it save in the colors i wrote it
The onTextChanged method is invoked to tell you that within CharSequence s, number of character count beginning at start have just replaced old text that had length before.
What is happening is that when user presses backspace, start is at the upper limit of your charsequence i.e. If you had seven character before, start is 6 which is the same as the last element. You are doing start+1 which is always a number out of index range.
myedittext.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(start < s.length() - 1 || count > before){
spannableString.setSpan(new ForegroundColorSpan(Color.parseColor(txtColor)), start, start+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
Didn't get to try that code but it should work. It's just to show you an idea of what you are doing wrong and what you should be doing.
When you delete text from the end of the string, the onTextChanged() method will be invoked with values representing the fact that the string is now shorter. It looks like you've written your code to always assume that the length will be longer; you're coloring in the just-typed character. But if you delete a character instead, you probably don't want to do this.
You could add a check to make sure that count is greater than before, this at the very least will indicate that text was added to the string.
if (count > before) {
spannableString.setSpan(...);
}

how to avoid editText change using textWatcher?

I have an editText that i want to control in length.
how can i avoid the user from entering a character which will lead the text to be longer than X ?
I have thought to use beforeTextChanged(CharSequence s, int start, int count,
int after) {
but then i'm not sure how to skip adding the character if i want.
The length is determined dynamically - getting this from the server side on activity start
Well, if you need to stop the user from entering a text longer than x, simply put android:maxLength="x" as an attribute for your EditText.
Or,
mEditText.setFilters( new InputFilter[]
{
new InputFilter.LengthFilter(<length>)
} );
use following property in edittext
android:maxLength="10"

custom phone number formatting

In my Android application I want create my own phone number formatting but still couldn't find a way to do this.
I read about phone number libs and so on but still couldn't find a way to do this because all libs is working fine with US, German, French and other formats. I want to support Russian and these libs doesn't work fine.
The only way is I have to create my own formatting.
for example if I type
79123456789
it have to be formatted like in here
+7(912)345-67-89
I found libs for IOS (SHSPhoneTextField) but in Android I didn't.
Could anyone just tell me good solution in here?
mPhoneNumber.addTextChangedListener(new PhoneNumberFormattingTextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (charSequence.length() == 11)
mPhoneNumber.setText(PhoneNumberUtils.formatNumber(charSequence.toString()));
}
#Override
public void afterTextChanged(Editable editable) {
}
});
Maybe this will help (PhoneNumberUtils): http://developer.android.com/reference/android/telephony/PhoneNumberUtils.html
A little example:
String formattedNumber = PhoneNumberUtils.formatNumber(unformattedNumber);
This will automatically format the number according to the rules for the country the number is from.
Look at PhoneNumberUtils for more options.
You shoul use PhoneNumberUtils with the desired Locale like this:
Locale localeRU = new Locale("ru","RU");
String formattedNumber = PhoneNumberUtils.formatNumber(unformattedNumber, PhoneNumberUtils.getFormatTypeForLocale (localeRU));
Have a look for the appropriate Locale here.
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (charSequence.length() == 11)
Locale localeRU = new Locale("ru","RU");
mPhoneNumber.setText(PhoneNumberUtils.formatNumber(charSequence.toString(), localeRU));
}

Filter Input in Real-Time?

I have an EditText (accepts 0-9) with a listener. I want to grab input as it's entered, apply a calculation, and display it in the same EditText box.
The box initially displays $0.00. When the user inputs a 2, I want to grab that from the box, parse it to remove the $ and decimal, convert it to an int... divide it by 100 and put a $ in front of it. After setText, it should display $0.02. If they then press 5, I'll grab it, parse it, end up with 25, do the math and it should display $0.25, etc.
I don't know if this is the best way, I'm open to new ideas. Here is my current code:
mEditPrice.addTextChangedListener(new TextWatcher(){
DecimalFormat dec = new DecimalFormat("0.00");
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
String userInput = mEditPrice.getText().toString().replaceAll("[^\\d]", "");
int userInputInt = Integer.parseInt(userInput);
mEditPrice.setText("$"+dec.format(userInputInt / 100));
}
There's a few issues to deal with here before you can achieve the kind of functionality you desire.
Whenever you deal with a TextWatcher you need to be careful when setting the text of the EditText object being watched. The reason for this is that every time you call setText on it, it will trigger the watcher again, causing your code to go into an infinite loop.
To prevent this, you should set the value of text you want to set into a variable outside of the onTextChanged method. When entering the method, check against this variable and only perform your processing code if the value is different from the CharSequence.
The integer variable userInputInt, when divided by 100, will be equal to zero.
This should be changed to a double to produce values like 0.02 etc.
After those changes we can get the EditText to show $0.02 after entering a 2. But because we have set the value of the EditText in code, the next entry into the EditText will be added to the beginning of the text. Then if we enter a '5' we get $50.02.
To overcome this, the last thing we need to do is set the position of the EditText to the end of the string, using the set position method.
Here's the final solution:
private String value;
mEditPrice.addTextChangedListener(new TextWatcher(){
DecimalFormat dec = new DecimalFormat("0.00");
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().equals(value)){
String userInput = mEditPrice.getText().toString().replaceAll("[^\\d]", "");
double userInputDouble = Double.parseDouble(userInput);
value = ("$"+dec.format(userInputDouble / 100));
mEditPrice.setText(value);
mEditPrice.setSelection(value.length());
}
}
});

Categories