如何在 ProgressBar 在 android 中可见时禁用用户交互?

How to disable user interaction while ProgressBar is visible in android?

我正在使用自定义 ProgressBar。现在,当任务正在进行时,我会显示进度条,但用户仍然可以与视图和控件进行交互。 如何在整个视图上禁用用户交互,就像 ProgressDialog 一样,当它可见时。

我是否需要在主视图之上使用透明视图并在该视图上显示进度条并在任务完成后隐藏该视图。

或者只是获取我的 parentView 的 ID 并将其设置为禁用?但那样我就无法调暗背景,就像 view/Activity/Fragment 上出现对话框时发生的情况一样。正确的?

我只想知道在进度条可见时禁止用户进行任何交互的方法。

谢谢

使用文档默认方法progressbar.setCancelable(false)

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

要禁用用户交互,您只需添加以下代码

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

要恢复用户交互,您只需添加以下代码

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

像这样在您的 xml.Something 中添加进度条

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

在 MainActivity 中,当按下按钮时显示进度条并禁用用户交互。

@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);
        }
    });
}

并且当用户 backPressed 时,您再次删除进度条保留用户 interaction.Something 像这样

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

如果要添加禁用和灰色显示功能,您需要在 xml 布局文件中添加一个填充父项的线性布局。将其背景设置为#B0000000,并将其 visibilty 设置为 GONE。然后以编程方式将其 visibility 设置为 VISIBLE.

希望对您有所帮助!

刚刚设置:

android:clickable="true" 

在你的 xml

<ProgressBar...

唯有如此神奇!

我通过向 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>

使根布局可点击

android:clickable="true"

注意: 在我的主视图中,我将 RelativeLayout 作为根,并在根布局中的最后一个位置添加了 above-mentioned 代码(最后child).

希望对您有所帮助!!

制作一个背景透明的对话框。 getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 的问题在于,当应用程序进入后台并返回时,用户将能够与 UI 组件进行交互,需要更多处理。所以为了阻止 UI 做一个透明的对话框,如果你想为 hide/show 设置时间。在可运行的线程中执行此操作。所以解决方案将是

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);

将您的父布局设为相对布局并添加:

    <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>

如果您的 UI 中有浮动按钮,它们仍会占据所有焦点并在进度条可见时保持可点击状态。对于此用途:(当您的进度条可见并在您制作进度条时重新启用它们 invisible/gone)

fb.setEnabled(false);

上扩展(双关语):

当你使用 kotlin 时,你可以使用扩展函数。这样你就有了一个快速漂亮的阻塞和解除阻塞的方法 UI.

fun AppCompatActivity.blockInput() {
    window.setFlags(
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
}

fun AppCompatActivity.unblockInput() {
    window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
}

fun AppCompatActivity.blockInputForTask(task: () -> Unit) {
    blockInput()
    task.invoke()
    unblockInput()
}

您可以在activity中使用阻塞和解除阻塞功能。此外,您还可以添加更多功能,例如显示 Toast 或其他内容。

在自定义视图或任何其他视图中使用它时,您只需将上下文转换为 activity 并使用函数。

使用blockInputForTask围绕简单的线性任务,blockInputunblockInput在不同范围需要时

您可以这样使用 blockInputForTask

blockInputForTask { 
    // Your lines of code
    // Can be multiple lines
}