web-dev-qa-db-ja.com

AndroidでProgressBarが表示されているときにユーザーの操作を無効にする方法

カスタムProgressBarを使用しています。タスクの進行中、進行状況バーが表示されますが、ユーザーはビューとコントロールを操作できます。 ProgressDialogが表示されるときと同じように、ビュー全体でユーザー操作を無効にするにはどうすればよいですか。

メインビューの上に透明なビューを使用し、そのビューに進行状況バーを表示し、タスクが完了したらそのビューを非表示にする必要がありますか。

または、単にparentViewのIDを取得して無効に設定しますか?ただし、ビュー/アクティビティ/フラグメントにダイアログが表示されたときのように、背景を暗くすることはできません。右?

私は、プログレスバーが表示されている間、ユーザーの操作を許可しない方法を知りたいだけです。

ありがとう

51

あなたの質問:AndroidでProgressBarが表示されているときにユーザーの操作を無効にする方法は?

ユーザー操作を無効にするには、次のコードを追加するだけです

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

ユーザーとの対話を取り戻すには、次のコードを追加するだけです

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

ここに例があります:注:ユーザーとの対話を無効化または保持する方法を示すための例を示しています

Xmlにプログレスバーを追加します。次のようなもの

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

また、ユーザーがbackPressした場合、プログレスバーを再度削除すると、ユーザーの操作が保持されます。

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

表示を無効にしてグレー表示にする機能を追加する場合は、親を埋める線形レイアウトをxmlレイアウトファイルに追加する必要があります。背景を#B0000000に、visibiltyGONEに設定します。次に、プログラムでvisibilityVISIBLEに設定します。

この助けを願っています!

103
Niyamat Ullah

ルートレイアウトを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があり、ルートレイアウト内の最後の位置(最後の子)に上記のコードを追加しました。

お役に立てれば!!

8
Nirav Dangi

設定するだけ:

Android:clickable="true" 

あなたのXMLで

<ProgressBar...

これだけが魔法になります!

ドキュメントのデフォルトメソッドprogressbar.setCancelable(false)を使用します

3
Ramesh sambu

背景が透明なダイアログを作成します。 getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);の問題は、アプリがバックグラウンドに戻って戻ってきたときに、ユーザーがUIコンポーネントとやり取りできるようになることです。 UIをブロックするために、透明なダイアログを作成し、非表示/表示の時間を設定する場合。これは実行可能なスレッドで行います。だから解決策は

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);
1
Qumber Abbas

親レイアウトを相対レイアウトとして作成し、これを追加します。

    <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にフローティングボタンがある場合でも、すべてのフォーカスを取得し、プログレスバーが表示されているときにクリック可能のままになります。この用途:(プログラムバーが表示されている場合、およびプログラムバーを非表示/非表示にした場合に再度有効にします)

fb.setEnabled(false);
1
AndroidGuy

受け入れられた回答 を拡張(意図したしゃれ)するには:

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()
}

アクティビティでブロック機能とブロック解除機能を使用できます。また、トーストなどを表示するなどの機能を追加できます。

カスタムビューまたは他のビューで使用する場合、コンテキストをアクティビティにキャストし、関数を使用するだけです。

blockInputForTaskを使用して単純な線形タスクを囲み、blockInputおよびunblockInputを使用します(異なるスコープで必要な場合)。

次のようにblockInputForTaskを使用できます。

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