I'm developing an android app where i've a refresh button in my action bar. This button call a function that re-open the same activity. This activity contains an asyncTask to load the content.
At the moment i'm encountering this problem. When i click on the refresh button it works fine, but if i click on the refresh button when the AsyncTask is still working (i've a progress bar to check the status) the app crashes.
The error that i receive is: NullPointerException
Is it possible to disable that button until the activity (and its AsyncTask) are completely loaded?
In your button's OnClickListener, from where you execute the AsyncTask, add this code:
button.setEnabled(false);
In onPostExecute() method of your AsyncTask, place this:
button.setEnabled(true);
If you also give the 'cancel' option to the user(i.e. if you have overridden the onCancelled() method in your AsyncTask), enable the button in onCancelled().
Edit 1:
Declare a boolean flag in your activity:
boolean menuButtonIsEnabled = true;
In your OnClickListener, set this flag to false:
menuButtonIsEnabled = false;
In onPostExecute() method of your AsyncTask:
menuButtonIsEnabled = true;
Override the onPrepareOptionsMenu(Menu) method in your activity:
#Override
public boolean onPrepareOptionsMenu (Menu menu){
super.onPrepareOptionsMenu(menu);
MenuItem button = menu.findItem(R.id.whatever_menu_button);
if(menuButtonIsEnabled){
button.setEnabled(true);
} else {
button.setEnabled(false);
}
return true;
}
In your onClickListener, the first thing you do is deactivate the button. This way it cannot be clicked again until you reactivate it :
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View target) {
target.setClickable(false);
target.setEnbled(false);
// Start your asynctask
}
}
in your AsyncTask.onPostResult(), you can reactivate the click on the button.
Nota: setClickable(false) prevents the button from reacting to clicks events, but setEnabled(false) also usually changes the appearance of the button.
You can try to disable the button from onPreExecute in AsyncTask and enable the button from onPostExecute in AsyncTask
You can check the status of your task.... On click of refresh button...
if(yourAsyncTaskObject != null && yourAsyncTaskObject.getStatus() != AsyncTask.Status.RUNNING){
then start your activity again here
}
Related
I have a problem
I have a non cancelable custom dialog
which mean this custom dialog can only close if presses buton inside the custom dialog, so it won't cancel on backpress or click outside
I tried setCancelable(false) and it works however in my activity I have a onBackPressed and whenever my non cancelable dialog show onBackPressed wont trigger when I click back button because I think they conflict
is their a solution to do this?
EDIT: The purpose is I want the user to click button ok, or skip inside the custom dialog which means this dialog is required before proceeding to next activity
also in onBackPressed since I am using fragment whenever user press back it changes to previous fragment
sorry for lacking of explanation
my code is this
Dialog
dialog_welcome_navigation = DialogUtils.showCustomDialog(context, R.layout.dialog_welcome_navigation);
dialog_welcome_navigation.setCancelable(false); // disable closing dialog with back pressed
dialog_welcome_navigation.setCanceledOnTouchOutside(true);
and the onBackPressed
#Override
public void onBackPressed(){
Log.d("TAG", "--back--");
}
After searching I have found a solution thanks to this SO answer
https://stackoverflow.com/a/25251122/3481654
I add a setOnKeyListener on my dialog
dialog_welcome_navigation.setOnKeyListener(dialogWelcomeNavigationOnKey);
private DialogInterface.OnKeyListener dialogWelcomeNavigationOnKey = new DialogInterface.OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == android.view.KeyEvent.KEYCODE_BACK) {
dialog_welcome_navigation.dismiss();
// move other fragment
return true;
}
return false;
}
};
as title says, how to make my ripple effect on ImageButton (ripple effect assigned to this ImageButton) activated on backpressed() without back to the previous activity
with a bit of logic you could achieve that easily. what i thought of is that you have a method lets call it doSomething();
boolean onBackpressed = false;
private void doSomthing() {
if(onBackpressed){
finish();
}else{
// do anything else that the button wants to do;
}
}
now onBackpressed() you could do this
#Override public void onBackpressed() {
onBackpressed = true;
myImageButton.performClick(); // myImageButton.callOnClick()
}
P.S: that i didn't call super.onBackpressed(); so we can control the back press without existing the app.
of course your imageButton click listener calls doSomething() method.
When a PopupWindow is showing, clicking a button outside of PopupWindow's area only dismisses the PopupWindow, but the button's click listener doesn't respond. My question is, why doesn't the button's click listener respond?
private OnClickListener mSiftClickListener = new
View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSiftPopwin != null && mSiftPopwin.isShowing()) {
ToastShow.makeText(mContext, "yes"); //never show
} else {
showSfitPopwin();
}
}
};
My onClickListener has two functions, showSiftPopwin and ToastShow, when Popwin is showing, click it again, Popwin dismiss but this onClick listener has't been invoked.
This is the expected behaviour.
A popup window will consume any touch events on the screen until it is dismissed. The touch event you mentioned does not get through to your button, and no click is performed.
You should move the button code into an OnDismissListener, if you want it to run whenever the window is dismissed.
So I have a button that initiates communication to a server. However, when I try to disable the button from within the on click (to stop multiple clicks) it doesn't happen until the on click ends. This is a problem as the server communication means it takes a while for the method to execute. I saw a previous question that was answered by using flags to stop the multiple clicks (and it was stated that it is a known bug that buttons cannot be immediately inactivated). Is there now any other more elegant solution to this problem or is flags still the only way?
in Button's onClick()
You can,
button.setEnabled(false);
what is did when I had this problem is use a boolean flag for this, here is a sample code for using a flag:
boolean isClicked = false;
Button btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!isClicked) {
isClicked = true;
// CONNECT TO SERVER
isClicked = false;
}
}
You can hide the button,
button.setVisibility(View.INVISIBLE);
or Disable the button
button.setEnabled(false);
or Keep a flag using boolean
I have this code here
ToggleButton toggleAlarm = (ToggleButton) d.findViewById(R.id.toggle_alarm);
toggleAlarm.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
Log.d("alarmCheck","ALARM SET TO TRUE");
sched.setAlarm(true);
}
else
{
Log.d("alarmCheck","ALARM SET TO FALSE");
sched.setAlarm(false);
}
}
});
I have to keep track if its ON or OFF. But when I logged something to logcat where it is on or off, it won't do a thing. I don't know, what is wrong, because on my other code same, syntax but it works I just copy paste it and change only the ToggleButton variable.
EDIT
I have observed, with the help of cdr. Powell of course, that when you put this code block, the one that I have posted, inside another anonymous listener, say listener for a save button, the checkOnChangedListener is broken, it doesn't function well inside another anonymous listener, but the one thing that I don't understand is that, there is also a outer listener in my code, it is like a button to display a dialog box and inside that dialog box, there is an add button that opens another dialog box which has that toggle button and another button for save or add which closes that dialog and returns to the previous dialog which will then display the newly added record, so anyone of you have an idea why is it broken when i put it inside a listener for a save button but works fine in a outer listener.
try this, May be the problem is with import
toggleAlarm.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
Log.d("alarmCheck","ALARM SET TO TRUE");
sched.setAlarm(true);
}
else
{
Log.d("alarmCheck","ALARM SET TO FALSE");
sched.setAlarm(false);
}
}
});
Try toggleAlarm.isChecked() too see if the button is checked or not.
In case toggleAlarm.isChecked() does not work for you you could always.
boolean _isChecked = false;
((ToggleButton) d.findViewById(R.id.toggle_alarm)).setOnClickListener(new OnOnClickListener() {
public void onClick(View arg0) {
_isChecked = !isChecked;
if(_isChecked()) {
Log.d("alarmCheck","ALARM SET TO TRUE");
sched.setAlarm(true);
}
else {
Log.d("alarmCheck","ALARM SET TO FALSE");
sched.setAlarm(false);
}
}
});
So i have observed, with the help of cdr. powell of course, that when u put this code block, the one that i have posted, inside another anonymous listener, say listener for a save button, the checkOnChangedListener is broken, it doesn't function well inside another anonymous listener, but the one thing that i don't understand is that, there is also a outer listener in my code, its like a button to display a dialog box and inside that dialog box, there is an add button that opens another dialog box which has that toggle button and another button for save or add which closes that dialog and returns to the previous dialog which will then display the newly added record, so anyone of you have an idea why is it broken when i put it inside a listener for a save button but works fine in a outer listener.