I have a TextWatcher set up and working (nearly) exactly as I want it. However, I would like this TextWatcher to stop as soon as the user enters a '.'. The only solution I have found so far crashes the app if the user entirely deletes the text. It is also important that the ENTIRE TextWatcher ends at the moment the user enters a '.'.
I have tried placing the TextWatcher within the loop, however it doesn't seem to work.
private TextWatcher userEnterListener = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if(after==0) {
shownText = "Please try again";
}
else if(after==1) {
shownText = "A";
}
else if(after==2) {
shownText = "An";
}
else if(after==3) {
shownText = "And";
}
else if(after==4) {
shownText = "Andr";
}
else if(after==5) {
shownText = "Andro";
}
else if(after==6) {
shownText = "Androi";
}
else if(after==7) {
shownText = "Android";
}
else if(after==8) {
shownText = "Android A";
}
else if(after==9) {
shownText = "Android Ap";
}
else if(after==10) {
shownText = "Android App";
}
else {
shownText = "Please try again";
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
recordedString = (s.toString());
update();
}
};
maybe this could work:
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(s.toString().equals("Android App") && start == '.'){
//here add an Empty TextWatcher to the EditText who has this TextWatcher added.
}
recordedString = (s.toString());
update();
}
Related
I am building a proto social network and I give the possibility to my users to Tag another user with the # , I'm using an autocomplete textview to show the dialog with the users # searched but I need to know when a user typed "#" and the letters following in the editext . I found this answer and it's exaclty what I need BUT I dont want to only get one character. I want the whole word to make a search in my database . Example, user types "#Jordan" in the middle of his paste text . I need to get the "#" and the "#Jordan " . How can I do it ?
Here s an example of my code
private final TextWatcher textWatcher = 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 (!TextUtils.isEmpty(s) && start < s.length()) {
if (!mentionAdapter.isEmpty()) {
mentionAdapter.clear();
}
String lastWord = s.toString().substring(s.toString().lastIndexOf(" ") + 1);
if (lastWord != null){
if (lastWord.length() != 0) {
switch (lastWord.charAt(0)) {
case '#':
if (getAdapter() != hashtagAdapter) {
setAdapter(hashtagAdapter);
}
break;
case '#':
if (getAdapter() != mentionAdapter) {
setAdapter(mentionAdapter);
}
break;
}
}
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
I am aiming you are working on android java so here is the answer to your question
EditText editText = (EditText)findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// 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 onTextChanged(CharSequence s, int start, int before, int count) {
try {
String capturedString = getText(s);
} catch (Exception e) {
e.printStackTrace();
}
}
});
this function will work whenever you tab spacebar "#Jordan " you will get string after '#' and before ' ' means you will get "Jordan" as a string
public String getText(String s) {
String startChar = "#";
String endChar = " ";
String output = getStringBetweenTwoChars(s, startChar, endChar);
System.out.println(output);
}
here is getStringBetweenTwoChars function
public String getStringBetweenTwoChars(String input, String startChar, String endChar) {
try {
int start = input.indexOf(startChar);
if (start != -1) {
int end = input.indexOf(endChar, start + startChar.length());
if (end != -1) {
return input.substring(start + startChar.length(), end);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return input;
}
You can do that by following code, If you want to #java from the string
**Hello this is #java the best programming language **
edt.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(final CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
String str = editable.toString();
String seperator = "#";
int seoPos = str.indexOf(seperator);
Pattern pattern = Pattern.compile("\\s");
Matcher matcher = pattern.matcher(str);
boolean found = matcher.find();
if (seoPos != -1 && !found){
Log.d("TextChanged0","current Char "+str.substring(seoPos-1+seperator.length()));
}
}
});
String last = s.toString().substring(s.toString().lastIndexOf(" ") + 1);
Inside EditText I want to know how to capitalize on specific words. The code is below.
editText.addTextChangedListener(new TextWatcher() {
private static final String KEYWORD = "rain";
private static final String KEYWORD1 = "music";
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
onSaveNote();
}
#Override
public void afterTextChanged(Editable s) {
onSaveNote();
try {
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 = editText.getText().toString().indexOf(KEYWORD, i);
if (i != -1) {
s.setSpan(new InputFilter[]{new InputFilter.AllCaps()}, i, i + KEYWORD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
I tried searching for this but not found any. InputFilter doesn't work. How to do this?
If you know value of your text and start and end index of your text.
editText.getText().toString().substring(startIndex, endIndex).toUpperCase();
You can find start index in text like this:
editText.getText().toString().indexOf(KEYWORD)
and end index like this:
editText.getText().toString().indexOf(KEYWORD) + KEYWORD.length()
In afterTextChanged(), do the following:
#Override
public void afterTextChanged(Editable s) {
onSaveNote();
String[] words = s.toString().split("\\s+");
String output = "";
for (String word : words) {
if (word.equalsIgnoreCase(KEYWORD) || word.equalsIgnoreCase(KEYWORD1)) {
output += word.toUpperCase(Locale.getDefault()) + " ";
} else {
output += word + " ";
}
}
editText.setText(output.trim());
}
I am using this code to add a dash('-') in a phone number after the 3rd and 4th number. The code is working just fine. My problem is that when I press backspace, I can't remove the dash. I can even add dots and I can delete them if I press backspace, but with dash it's just impossible.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MainActivity.headerName.setText("Verification");
phoneNumber = (EditText) getActivity().findViewById(R.id.phoneEditText);
int grup = 1;
phoneNumber.addTextChangedListener(new TextWatcher() {
int keyDel;
String a= phoneNumber.getText().toString();
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
phoneNumber.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KEYCODE_DEL) {
a = a.replace("-" , "");
phoneNumber.setText(a);
keyDel = 1;
}
return false;
}
});
if (keyDel == 0) {
int len = phoneNumber.getText().length();
if(len == 3 || len == 7) {
phoneNumber.setText(phoneNumber.getText() + "-");
phoneNumber.setSelection(phoneNumber.getText().length());
}
} else {
if(KeyEvent.isModifierKey(KEYCODE_DEL)) {
a = a.replace("-" , "");
phoneNumber.getText().toString().replace("-" , "");
phoneNumber.setText(a);
}
keyDel = 0;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
I'm guessing that your UI widget is formatting its text. So, after you remove the hyphen, the widget is putting it back.
I suggest you leave the widget alone. Instead, when you need to use the phone number, remove the formatting characters from the value.
String.replaceAll("[^\\d]", "")
You would use this code when retrieving the value from the widget for some external use. So, you might have a method
public String getPhoneNumberUnformatted() {...}
That returns only the digits of the widget's value.
Probably you want to jump to Update 2 and check the code if needed
I am building a barcode scanner and having difficulty in passing data that I have captured from an inner class that extends BroadcastReceiver to MainActivity class, I do understand the difference between static and non static objects, but I got stuck.
Cant invoke my logic method from the inner class.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
protected void onCreate(Bundle savedInstanceState){...}
public void Logic(String result){// Do something...}
//Inner Class
public static class ScanResultReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {...
// data here captured fine!
// Here I want to send my data to MainActivity Logic(result)
Logic(result);
}
}
If I make "Logic()" as Static method, I get a lot of errors regards to calling non static from static method from Toaster/variables..etc
Update
This method is inside MainActivity, I do want to call it from the inner class
public void Logic(String result) throws Exception {
//prepare the results
if (mDecodeResult.decodeValue.substring(0, 1).equals("{") && mDecodeResult.decodeValue.substring(mDecodeResult.decodeValue.length() - 1).equals("}")) {
if (!(mDecodeResult.decodeValue.equals("SCAN AGAIN"))) {
mDecodeResult.decodeValue = mDecodeResult.decodeValue.substring(1);
mDecodeResult.decodeValue = mDecodeResult.decodeValue.substring(0, mDecodeResult.decodeValue.length() - 1);
}
}
if (mDecodeResult.decodeValue.equals("SCAN AGAIN")) {
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received! Please Scan Again", Toast.LENGTH_SHORT);
toast.show();
} else if (mDecodeResult.decodeValue != null && tourFlag) {
String formattedDate = getTime();
String scanContent = mDecodeResult.decodeValue;
boolean found = false;
if (ForcedOrRandom.equals("Random")) {
String[] b;
for (String l : ToBeScanned) {
b = l.split(":");
if (scanContent.equals(b[0])) {
Log.d("remove", "scanned: " + scanContent);
Log.d("remove", "remove : " + b[0]);
found = true;
}
}
} else if (ForcedOrRandom.equals("Forced")) {
String[] b;
for (String I : FTobeScannedNext) {
b = I.split(":");
if (scanContent.equals(b[0])) {
Log.d("remove", "scanned: " + scanContent);
Log.d("remove", "remove : " + b[0]);
found = true;
}
}
}// end Skip/Forced
if (listLoaded && found) {
theResult[resultCount].setTourID(currentTourId);
theResult[resultCount].setBarcode(scanContent);
BarcodeObject a = getBarcodeInfo(scanContent);
if (ForcedOrRandom.equals("Random")) {
} else {
if (myTimer != null) {
myTimer.cancel();
Timer = (TextView) findViewById(R.id.timertext);
Timer.setText("");
PlayOrPause.setVisibility(View.INVISIBLE);
}
boolean isTimed = a.getForceNextBarCode().equals("");
if (!(isTimed)) {
PlayOrPause = (ImageButton) findViewById(R.id.PlayPause);
PlayOrPause.setVisibility(View.VISIBLE);
PlayOrPause.setImageResource(R.drawable.pause);
final AlertDialog.Builder timealert = new AlertDialog.Builder(this);
PlayOrPause.setEnabled(true);
long duration = Integer.parseInt(a.getForceNextBarCode());
duration = duration * 60000;
myTimer = new CountDownTimer(duration, 1000) {
#Override
public void onTick(long millisuntilFinished) {
int seconds = (int) (millisuntilFinished / 1000) % 60;
int minutes = (int) ((millisuntilFinished / (1000 * 60)) % 60);
Timer = (TextView) findViewById(R.id.timertext);
Timer.setText(minutes + ":" + seconds);
timeLeft = millisuntilFinished;
}
String value = "";
#Override
public void onFinish() {
Timer = (TextView) findViewById(R.id.timertext);
theResult[resultCount].setScanstatus(scanStatusTimeElapsed);
timealert.setTitle("Site Secure");
timealert.setMessage("Time Elapsed! Enter reason");
// Set an EditText view to get user input
final EditText input = new EditText(MainActivity.this);
timealert.setView(input);
timealert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = input.getText().toString();
// Do something with value!
while (value.equals("")) {
timealert.setView(input);
timealert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = input.getText().toString();
}
});
}
theResult[resultCount].setComments(value);
}
});
timealert.setIcon(android.R.drawable.ic_dialog_alert);
timealert.show();
Timer.setText(R.string.Time_Elapsed);
}
};
myTimer.start();
}
}
theResult[resultCount].setBarcodeID(a.getBarCodeId());
theResult[resultCount].setDateScanned(formattedDate);
theResult[resultCount].setSkipped(getResources().getString(R.string.Scanned));
}// end big if listLoaded && found
contentTxt.setText(scanContent);
Toaster(getResources().getString(R.string.TScan_Complete));
if (mainScanCounter == 0) {
if (tourDecider(scanContent)) {//tour decider is called to determine if this is boolJanamScanner random or forced tour
tourId = scanContent;
if (!(readFileOffline(siteSecurePath + "/doneTourNumber.txt").equals(""))) {
SYNC.setEnabled(true);
}
}
} else if (mainScanCounter > 0) {
if (ForcedOrRandom.equals("Random")) {
ListManager(scanContent);
} else {
ForcedListManager(scanContent);
}
}
} else if (mDecodeResult.decodeValue != null && officerScanFlag) {
TextView officertextview = (TextView) findViewById(R.id.officerid);
UserObject theofficer = getUserInfo(mDecodeResult.decodeValue);
if (theofficer == null) {
popUps("Error", "Invalid Officer ID, Please Rescan", "TITLE");
officerScan.setEnabled(true);
} else if (theofficer != null) {
// officer ID found need to store it for backup
officerId = theofficer.getOfficerid();
makeFileOffline(officerId, "officerID");
officertextview.setText(theofficer.getUsername());
officerScanFlag = false;
startTimersOfficerID = getTime();
tourBtn.setEnabled(true);
}
}
if (mDecodeResult.decodeValue != null && exceptionFlag) {
Log.d("check", "exception was clicked");
String ex_result = mDecodeResult.decodeValue;
for (int i = 0; i < theExceptions.length; i++) {
if (!(theExceptions[i].getBarcode().equals(ex_result))) {
String refnum = theExceptions[i].getRefNum();
i = theExceptions.length;
theResult[resultCount - 1].setException(refnum);
}
}
exceptionFlag = false;
Toaster(getResources().getString(R.string.TScan_Complete));
}
} // Logic Ends
Update 2
Not sure if I need to have another thread for this but I will put what I have found, my issue have narrowed to the following:
I am waiting on an intent called
<action android:name="device.scanner.USERMSG" />
with a permission
android:permission="com.permission.SCANNER_RESULT_RECEIVER"
now my issue
if a user tap button and released in less than .5 second onKeyup() event will be fired before my onReceive() that is inside the static class which is extends BroadcastReceiver, and that causes problem because Logic() will be invoked before updating the String inside onReceive()
if user hold the button long enough, onReceive will be invoked and everything is good and happy.
How can I make sure that onReceive() always invoked first?
public boolean onKeyUp(int keycode, KeyEvent event) {
if (keycode == 221 || keycode == 220 || keycode == 222) {
Logic(result);
}
return true;
}
Move this line of code:
public void Logic(String result){// Do something...}
inside your class ScanResultReceiver and it will work for sure. Your code should look like this:
public static class ScanResultReceiver extends BroadcastReceiver {
public ScanResultReceiver() {
//empty constructor
}
#Override
public void onReceive(Context context, Intent intent) {...
// data here captured fine!
// Here I want to send my data to MainActivity Logic(result)
Logic(result);
}
public void Logic(String result){/* ... */}
}
How to make make user input of 10 digit mobile number into 3-3-4 format?
example of 9848098480 into (984)-809-8480 in android??
Simply use the PhoneNumberFormattingTextWatcher, just call:
editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
Addition
To be clear, PhoneNumberFormattingTextWatcher's backbone is the PhoneNumberUtils class. The difference is the TextWatcher maintains the EditText while you must call PhoneNumberUtils.formatNumber() every time you change its contents.
OR
You can use this:
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="phone" />
Then try this code:
final EditText text = (EditText) findViewById(com.and.R.id.editText1);
text.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
boolean flag = true;
String eachBlock[] = text.getText().toString().split("-");
for (int i = 0; i < eachBlock.length; i++) {
if (eachBlock[i].length() > 4) {
flag = false;
}
}
if (flag) {
text.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL)
keyDel = 1;
return false;
}
});
if (keyDel == 0) {
if (((text.getText().length() + 1) % 5) == 0) {
if (text.getText().toString().split("-").length <= 3) {
text.setText(text.getText() + "-");
text.setSelection(text.getText().length());
}
}
a = text.getText().toString();
} else {
a = text.getText().toString();
keyDel = 0;
}
} else {
text.setText(a);
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
}
});
use Himanshu Agarwal's method or just do:
String number = "1234567899";
System.out.println("(" + number.substring(0, 3) + ")-"
+ number.substring(3, 6) + "-" + number.substring(6));
ouput:
(123)-456-7899