Cancel postDelayed within onTextChanged - java

I want make Web service called after by 3 seconds every time you update value of EditText, but in case if you update value of EditText before 3 seconds, remove all delayed callback and wait for 3 sec for Web Service call.Please see my cod and let me know proper way to do this task
#Override
public void onTextChanged(final CharSequence s, int start, int before, int count) {
if (s.length() > 2) {
final Handler handler = new Handler();
handler.removeCallbacksAndMessages(null);
handler.postDelayed(
new Runnable() {
#Override
public void run() {
// Soap call
}
},
3000);
}
}

Try this code
It will solve your issue.
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
//Soap Call;
}
};
editText.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) {
handler.removeCallbacks(runnable);
}
#Override
public void afterTextChanged(Editable s) {
handler.postDelayed(runnable, 3000);
}
});

Try this .
long lastTime = System.currentTimeMillis();
final Handler handler;
public void onTextChanged(final CharSequence s, int start, int before, int count) {
if(s.length() > 2) {
if (System.currentTimeMillis() - lastTime > 3000) {
startWork();
}
lastTime = System.currentTimeMillis();
}
}
public void startWork() {
if (null == handler) {
handler = new Handler();
}
handler.removeCallbacksAndMessages(null);
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Soap call
}
}, 3000);
}

Related

How to show dropdown of AutoCompleteTextView after some seconds of last typed letter?

Well, I have to call api to get data from server and show in AutoCompleteTextView. I can fetch that search results perfectly but the problem is that when, I type single letter in to the AutoCompleteTextView then each and every time api executes which is not good user experience and it takes too much time.
Although, I have created some logic to get data after some seconds but it only works when I type next letter.
String sec;
home_name_search.addTextChangedListener(new TextWatcher() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void afterTextChanged(Editable s) {
Format sdf = new SimpleDateFormat("ss");
if (s.length() >= 3) { // minimum 3 letters to execute api.
if (s.length() == 3) {
sec = sdf.format(new Date());
} else {
try {
SimpleDateFormat sdf2 = new SimpleDateFormat("ss");
String Cdate = sdf.format(new Date());
Date d1 = sdf2.parse(sec);
Date d2 = sdf2.parse(Cdate);
long CompareDate = d2.getTime() - d1.getTime();
if (CompareDate >= 3000) {
//here my api executes in AsyncTask.
sec = sdf.format(new Date());
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}
});
You can use the timer to wait:
Timer timer = new Timer();
final long DELAY = 1000; // You can give the time(1000 =1 sec.)
home_name_search.addTextChangedListener(
new TextWatcher() {
#Override public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(final Editable s) {
timer.cancel();
timer = new Timer();
timer.schedule(
new TimerTask() {
#Override
public void run() {
// You can call API.
}
},
DELAY
);
}
});

How will i add background service for countdown timer

long duration = TimeUnit.MINUTES.toMillis((long) 6.3);
new CountDownTimer(duration, 1000) {
#Override
public void onTick(long l) {
String sDuration = String.format(Locale.getDefault(),"%02d : %02d"
,TimeUnit.MILLISECONDS.toMinutes(l)
,TimeUnit.MILLISECONDS.toSeconds(l) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(l)));
orderCountdown.setText(sDuration);
}
#Override
public void onFinish() {
orderCountdown.setVisibility(View.GONE);
Toast.makeText(context,"asdasd",Toast.LENGTH_LONG).show();
}
}.start();
}
how can i add a background service for this code to work in background

How to add delay in Google Places API request?

I want to reduce request to Google Places API by adding delay for every user input but i am not sure how to implement this. This is what i usually do to add delay to my EditText waiting for user's input:
editTextEmail.addTextChangedListener(new TextWatcher() {
final Handler handler = new Handler();
Runnable runnable;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
isEmailValid = false;
textInputLayoutEmail.setError(null);
enableDisableButton();
handler.removeCallbacks(runnable);
}
#Override
public void afterTextChanged(Editable s) {
runnable = new Runnable() {
#Override
public void run() {
callGooglePlacesAPI()
}
};
handler.postDelayed(runnable, 1000);
}
});
This is my code to call Google PLaces API:
editTextLocation.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
editTextLocation.setShowSoftInputOnFocus(false);
searchLocation();
}
}
});
public void searchLocation(){
try
{
editTextLocation.clearFocus();
//hide soft keyboard
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY)
.build(getActivity());
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
}catch (Exception e){
e.printStackTrace();
}
}
Is there a way to do this? Please help give advice on this. Thank you.

How to use Handler Postdelayed in queue?

I have a situation, I created a button and a function like this.
...
public void BtnOnClick(View view) {
displayMsg();
}
...
private void displayMsg(){
handler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, 3000);
}
...
If I click the button once a Toast should appear after a 3 seconds delay.
But if I quickly click the button two or more times then all the Toasts appear at the same time after 3 seconds without delay of 3 seconds between every Toast it's not good. I want a 3 seconds gap/delay between every Toast appearance despite of simultaneous clicks.
Is there any solution?
If there are multiple handlers in a queue then each handler delayed time start after the previous handler delay time end.
You can queue the requests to make sure the toasts are displayed at an interval.
ArrayList<Runnable> requests = new ArrayList<>;
bool inProgress = false;
private void displayMsg(){
Runnable runnable = new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
inProgress = false;
if (requests.size() > 0) {
handler.postDelayed(requests.remove(0), 3000 + Toast.LENGTH_SHORT);
}
}
}
if (!inProgress) {
inProgress = true;
handler.postDelayed(runnable, 3000);
} else {
requests.add(runnable);
}
}
Try this:
private final Handler handler = new Handler() {
final int DELAY = 3000;
final int DELAY_MSG = 1;
final Queue<Runnable> pendingRunnables = new ArrayDeque<>();
#Override
public void dispatchMessage(Message msg) {
if (msg.what == DELAY_MSG) {
final Runnable r = pendingRunnables.poll();
if (r != null) {
r.run();
sendEmptyMessageDelayed(DELAY_MSG, DELAY);
}
} else {
pendingRunnables.add(msg.getCallback());
if (!hasMessages(DELAY_MSG)) {
sendEmptyMessage(DELAY_MSG);
}
}
}
};
...
// post action
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
});
Maybe you can use postAtTime:
AtomicLong previous = new AtomicLong(System.currentTimeMillis());
private void displayMsg(){
handler.postAtTime(new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, previous.updateAndGet(operand -> Long.max(operand + 3000, System.currentTimeMillis() + 3000)));
}

Handling Chat typing or Stop typing event (Android)

I am handling typing events if user enter text in editext typing function sends requests to server and use removed text i want to stoptyping function do work but its not working.
How to check if user have removed text after entering text
mEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
new Thread(new Runnable() {
#Override
public void run() {
try {
session.typing();
} catch (OmegleException e) {
e.printStackTrace();
}catch(NullPointerException e){
e.printStackTrace();
}
}
}).start();
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(final CharSequence s, final int start,
int before, int count) {
new Thread(new Runnable() {
#Override
public void run() {
try {
if(start==-1){
session.stopTyping();
}
} catch (OmegleException e) {
e.printStackTrace();
}catch(NullPointerException e){
e.printStackTrace();
}
}
}).start();
}
});
I changed to following :
mEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
lengthBeforeType = mEditText.getText().toString().length();
}
public void onTextChanged(final CharSequence s, final int start,
int before, final int count) {
lengthAfterType = mEditText.getText().toString().length();
new Thread(new Runnable() {
#Override
public void run() {
try {
if((lengthAfterType-lengthBeforeType)<0){
session.stopTyping();
}else{
session.typing();
}
} catch (OmegleException e) {
e.printStackTrace();
}
}
}).start();
int lenghtAfterType;
int lenghtBeforeType;
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
lenghtBeforeType = yourEdittext.getText.toString.Lenght;
}
public void afterTextChanged(Editable s) {
lenghtAfterType = yourEdittext.getText.toString.Lenght;
if((lenghtAfterType-lenghtBeforeType)<0){
// user while deleted text
}else{
// user while typing
}
}

Categories

Resources