How to disable user interaction while ProgressBar

2019-01-31 03:33发布

问题:

I am using a custom ProgressBar. Now while a task is going on, I am showing the progress bar, but user can still interact with the views and controls. How do I disable the user interaction on whole view just like a ProgressDialog does , when it is visible.

Do I need to use a transparent view on top of main view and show the progress bar on that view and hide that view once a task is completed.

Or just get the id of my parentView and set it disabled ? But then I won't be able to dim the background, just like what happens when a dialog appears on the view/Activity/Fragment. Right?

I just want to know the way to disallow the user from any interaction while the progressbar is visible.

Thanks

回答1:

Your question: How to disable the user interaction while ProgressBar is visible in android?

To disable the user interaction you just need to add the following code

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

To get user interaction back you just need to add the following code

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

Here is an example: Note:I am giving you just an example to show how to disable or retain user interaction

Add a progress bar in your xml.Something like this

<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:visibility="gone"/>

In MainActivity when a button pressed you show the progressbar and disable the user interaction.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mImageView = (ImageView) findViewById(R.id.imageView);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    mImageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mProgressBar.setVisibility(View.VISIBLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        }
    });
}

And when user backPressed you remove the progressbar again retain the user interaction.Something like this

  @Override
public void onBackPressed() {
    super.onBackPressed();
    mProgressBar.setVisibility(View.GONE);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}

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. Then programmatically set its visibility to VISIBLE.

Hope this help!



回答2:

just set:

android:clickable="true" 

in your xml

<ProgressBar...

Only this makes magic!



回答3:

I have fixed this issue by adding root layout to the ProgressBar.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:clickable="true"
    android:gravity="center"
    android:visibility="gone"
    android:id="@+id/progress">
    <ProgressBar
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:indeterminate="true"
        android:indeterminateTintMode="src_atop"
        android:indeterminateTint="@color/primary"/>
</LinearLayout>

Made the root layout clickable

android:clickable="true"

NOTE: In my main view, I had RelativeLayout as root and have added above-mentioned code inside the root layout at the last position (last child).

Hope this helps!!



回答4:

Use document default method progressbar.setCancelable(false)



回答5:

Make a dialog with transparent background. The issue with getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); is that when app will go in background and come back user will be able to interact with UI components, a lot more handling. So for blocking UI make a transparent dialog and if you want to set time for hide/show. Do this in a runnable thread. So the solution will be

public class TransparentDialogHelper {

    private Dialog overlayDialog;

    @Inject
    public TransparentDialogHelper() {

    }

    public void showDialog(Context context) {
        if (AcmaUtility.isContextFinishing(context)) {
            return;
        }
        if (overlayDialog == null) {
            overlayDialog = new Dialog(context, android.R.style.Theme_Panel);
            overlayDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);
        }
        overlayDialog.show();
    }

    public void hideDialog() {
        if (overlayDialog == null || AcmaUtility.isContextFinishing(overlayDialog.getContext())) {
            return;
        }
        overlayDialog.cancel();
    }
}

-------- Timer

Handler handler = new Handler();
handler.postDelayed( () -> {
    view.hideProgress();
}, 2000);


回答6:

Make your parent layout as Relative Layout & add this :

    <RelativeLayout ... >

    <other layout elements over which prog bar will appear>

<RelativeLayout android:id="@+id/rl_progress_bar"
                android:layout_width="match_parent" android:clickable="true"
                android:layout_height="match_parent" >
<ProgressBar android:id="@+id/pb"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true"
             android:indeterminateOnly="true"
             style="@android:style/Widget.DeviceDefault.ProgressBar"
             android:theme="@style/AppTheme.MyProgressBar"
    />
</RelativeLayout>

If you have floating buttons in your UI, they still grab all the focus & remain clickable when the progress bar is visible. for this use : (when your prog bar is visible & re-enable them when you make your prog bar invisible/gone)

fb.setEnabled(false);