Disable a whole activity from user action

Android

Android Problem Overview


Is there a simple way to disable a user interacting with an activity. To be done when there is an action running (and a spinning progress bar in the title bar)

EDIT: As it seems I was not clear enough I meant to say: while I already have a spinning progress bar, the user is still able to push any button on the activity, I want to disable the user from being able to do that while the task is running. I do not want to however disable each item on the screen one by one.

Thanks, Jason

Android Solutions


Solution 1 - Android

In order to block user touch events, use:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

To get touch events back, use:

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

EDIT: If you want to add a feature of disable and greyed out display, you need to add in your xml layout file a linear layout that fills the parent. Set its background to #B0000000 and its visibilty to Gone. Than programicly set its visibility to Visible.

Solution 2 - Android

If you need to disable event processing for a period of time (for instance, while you run an animation, show a waiting dialog), you can override the activity's dispatch functions.

To disable touch/clicks on any buttons, add these members/functions to your activity:

protected boolean enabled = true;

public void enable(boolean b) {
    enabled = b;
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    return enabled ? 
        super.dispatchTouchEvent(ev) : 
        true;        
}

Then just call enable(true/false) when you need to disable and enable the activity's normal event handling.

Solution 3 - Android

Use AsyncTask with ProgressDialog bundled.

  1. AsyncTask

  2. Progress Dialog

another useful example:

http://www.screaming-penguin.com/node/7746

Solution 4 - Android

I have solved this using a custom method - which I did not want to do:

public static void setViewGroupEnabled(ViewGroup view, boolean enabled)
	{
		int childern = view.getChildCount();
		
		for (int i = 0; i< childern ; i++)
		{
			View child = view.getChildAt(i);
			if (child instanceof ViewGroup)
			{
				setViewGroupEnabled((ViewGroup) child, enabled);
			}
			child.setEnabled(enabled);
		}
		view.setEnabled(enabled);
	}

If anyone finds a better way I'd like to hear about it! Thanks.

Solution 5 - Android

I solved this by adding an full screen blank image with a null click handler at the end on the XML layout.

Create a transparent PNG file in the drawables folder.

Add a full screen ImageView at the end of the XML layout referencing the image:

...
 <ImageView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:srcCompat="@drawable/img_mask"
     android:id="@+id/imgMask"
     android:scaleType="fitXY"
 android:visibility="gone"
     android:onClick="doNothingClick"
 />

Add the null click hander for the image to capture user touches:

public void doNothingClick(View v){
    // do nothing with the click
}

Add the code to disable the user touches:

private void StopTouches(int duration){
    findViewById(R.id.imgMask).setVisibility(View.VISIBLE);
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            findViewById(R.id.imgMask).setVisibility(View.GONE);
        }
    }, duration);
}

Solution 6 - Android

The code of Uriel Frankel (accepted response), works good, but in my case works after my request it's done :(. I want to block before it happend. Some one knows what is wrong in my code (I'm beginning in this..)

(this is a fragment)

   login_login_btn.setOnClickListener {

    if (validateInputs()){
        showSpinner()
        thread {
            doLogin()
        }
    } else {
        validationError("Validation Error","Checkout your inputs. Common errors: \npassword (at least 8 characters)")
    }

}

}

Function after OnViewCreated

fun showSpinner(){
    activity?.window?.setFlags(
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
    spinner.visibility = View.VISIBLE
}

Thank you (Y)

Solution 7 - Android

SpinningProgress in the title bar:

//onCreate(): 
activity.requestWindowFeature(FEATURE_INDETERMINATE_PROGRESS);

//and then: 
activity.setProgressBarIndeterminate(boolean indeterminate)

both in [Activity class][1]

Another option is using Progress Dialog (you might want to set cancelable to false on it).

[1]: http://developer.android.com/reference/android/app/Activity.html#requestWindowFeature(int) "Activity Class"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJasonView Question on Stackoverflow
Solution 1 - AndroidUriel FrankelView Answer on Stackoverflow
Solution 2 - AndroidricosrealmView Answer on Stackoverflow
Solution 3 - AndroidVladimir IvanovView Answer on Stackoverflow
Solution 4 - AndroidJasonView Answer on Stackoverflow
Solution 5 - AndroidPKanoldView Answer on Stackoverflow
Solution 6 - AndroidDiego Paredes ArenasView Answer on Stackoverflow
Solution 7 - AndroidPedro LoureiroView Answer on Stackoverflow