web-dev-qa-db-de.com

So deaktivieren Sie die Benutzerinteraktion, während ProgressBar in Android sichtbar ist

Ich verwende eine benutzerdefinierte Fortschrittsleiste. Während eine Aufgabe ausgeführt wird, wird der Fortschrittsbalken angezeigt. Der Benutzer kann jedoch weiterhin mit den Ansichten und Steuerelementen interagieren. Wie kann ich die Benutzerinteraktion in der gesamten Ansicht deaktivieren, genau wie ein ProgressDialog, wenn er sichtbar ist.

Muss ich eine transparente Ansicht über der Hauptansicht verwenden, die Fortschrittsleiste in dieser Ansicht anzeigen und diese Ansicht ausblenden, wenn eine Aufgabe abgeschlossen ist. 

Oder einfach die ID meines parentView abrufen und deaktivieren? Aber dann kann ich den Hintergrund nicht dimmen, genau wie bei einem Dialog in der Ansicht/Aktivität/Fragment. Recht? 

Ich möchte nur wissen, wie der Benutzer von jeglicher Interaktion ausgeschlossen wird, solange die Fortschrittsleiste sichtbar ist.

Vielen Dank

31

Ihre Frage: Wie kann ich die Benutzerinteraktion deaktivieren, während ProgressBar in Android sichtbar ist?

Um die Benutzerinteraktion zu deaktivieren, müssen Sie lediglich den folgenden Code hinzufügen

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

Um die Benutzerinteraktion wiederherzustellen, müssen Sie lediglich den folgenden Code hinzufügen

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

Hier ist ein Beispiel: Hinweis: Ich gebe Ihnen nur ein Beispiel, um zu zeigen, wie Sie die Benutzerinteraktion deaktivieren oder beibehalten können.

Fügen Sie eine Fortschrittsleiste in Ihre XML hinzu. So etwas

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

Wenn in MainActivity eine Schaltfläche gedrückt wird, zeigen Sie die Fortschrittsleiste an und deaktivieren die Benutzerinteraktion.

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

Und wenn der Benutzer zurückgedrückt wird, entfernen Sie den Fortschrittsbalken erneut, und die Benutzerinteraktion bleibt erhalten. So etwas

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

Wenn Sie eine Funktion zum Deaktivieren und Ausblenden der Anzeige hinzufügen möchten, müssen Sie Ihrer XML-Layoutdatei ein lineares Layout hinzufügen, das das übergeordnete Element ausfüllt. Setzen Sie den Hintergrund auf # B0000000 und visibilty auf GONE. Setzen Sie dann visibility programmgesteuert auf VISIBLE.

Ich hoffe das hilft!

81
Niyamat Ullah

Ich habe dieses Problem behoben, indem ich der ProgressBar das Root-Layout hinzugefügt habe. 

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

Das Grundlayout anklickbar gemacht

Android:clickable="true"

HINWEIS: In meiner Hauptansicht hatte ich RelativeLayout als root und habe oben genannten Code im Root-Layout an der letzten Position (letztes untergeordnetes Element) hinzugefügt.

Hoffe das hilft!!

4
Nirav Dangi

gerade eingestellt:

Android:clickable="true" 

in deiner XML 

<ProgressBar...

Nur das macht Magie!

Dokumentstandardmethode progressbar.setCancelable verwenden (false)

2
Ramesh sambu

Machen Sie einen Dialog mit transparentem Hintergrund. Das Problem mit getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); ist, dass der Benutzer mit den Komponenten der Benutzeroberfläche interagieren kann, wenn die App in den Hintergrund wechselt und zurückkommt. Um die Benutzeroberfläche zu blockieren, machen Sie einen transparenten Dialog und wenn Sie die Zeit für das Ausblenden/Anzeigen einstellen möchten. Tun Sie dies in einem ausführbaren Thread. Die Lösung wird also sein

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

Erstellen Sie Ihr übergeordnetes Layout als relatives Layout und fügen Sie Folgendes hinzu: 

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

Wenn Sie in Ihrer Benutzeroberfläche über schwebende Schaltflächen verfügen, wird der Fokus immer noch beibehalten und bleibt anklickbar, wenn die Fortschrittsleiste sichtbar ist. für diese Verwendung: (wenn Ihre Progleiste sichtbar ist und sie wieder aktivieren, wenn Sie Ihre Progleiste unsichtbar machen/verschwinden)

fb.setEnabled(false);
1
AndroidGuy

Um (Wortspiel beabsichtigt) auf die akzeptierte Antwort zu erweitern:

Wenn Sie Kotlin verwenden, können Sie Erweiterungsfunktionen verwenden. Auf diese Weise haben Sie eine schnelle und gut aussehende Methode zum Sperren und Entsperren der Benutzeroberfläche.

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

Sie können die Sperr- und Entsperrfunktionen in Ihrer Aktivität verwenden. Sie können auch weitere Funktionen hinzufügen, z. B. das Anzeigen eines Toasts oder Ähnliches.

Wenn Sie es in einer benutzerdefinierten Ansicht oder einer anderen Ansicht verwenden, können Sie den Kontext einfach in Aktivität umwandeln und die Funktionen verwenden.

Verwenden Sie blockInputForTask, um einfache lineare Tasks und blockInput und unblockInput zu umgeben, wenn sie in verschiedenen Bereichen benötigt werden.

Sie können blockInputForTask folgendermaßen verwenden:

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