chronométré modeless dialogue
-
29-09-2019 - |
Question
Est-il possible de montrer une boîte de dialogue modales - une boîte de dialogue qui permet à l'utilisateur d'interagir avec tout ce qui était à l'écran avant la boîte de dialogue, mais permet également à l'utilisateur d'interagir avec la boîte de dialogue si vous appuyez
Je connais Toasts, mais ils ne permettent pas d'interaction avec le menu contextuel.
Je connais Dialogs, mais ils sont modales et ne permettent pas d'interaction avec l'arrière-plan.
Je sais que des notifications, mais je veux quelque chose qui est visibile à l'écran.
Je veux essentiellement de pouvoir jouer à un jeu ou quelque chose et un pop-up apparaît que j'ai un nouvel e-mail ou quelque chose. Je peux cliquer pour voir mes e-mails, mais je peux attendre qu'il aille si je veux juste continuer à jouer mon jeu. Est-ce possible dans Android?
La solution
Oui, créer une activité avec un style Theme.Dialog
. Ceci est une activité normale qui ressemble à une boîte de dialogue, tout en étant modales et d'accepter les événements.
Exemple Un:
<activity android:name=".activity.dialog.PhotoDialog"
android:label="@string/photo_dialog_title"
android:theme="@android:style/Theme.Dialog"/>
Edité :
En effet Theme.Dialog
brouille l'activité sous-jacente et la rend inaccessible. J'ai eu une exigence similaire ici, je devais montrer télécharger dialogue de progression avec le texte et le bouton annuler. La prise principale est dans la mise en WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
et réinitialiser WindowManager.LayoutParams.FLAG_DIM_BEHIND
.
Création d'un dialogue avec un contenu personnalisé:
if (progressDialog == null) {
progressDialog = new Dialog(activityRequestingProgressDialog);
progressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
progressDialog.setContentView(R.layout.progress_upload);
progressBar = (ProgressBar) progressDialog.findViewById(R.id.progressBar);
progressText = (TextView) progressDialog.findViewById(R.id.progressText);
progressText.setText("0 %");
progressText.setTextSize(18);
Button buttonCancel = (Button) progressDialog.findViewById(R.id.btnCancel);
buttonCancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
cancelProgressDialog();
stopUpload("Upload cancelled.");
}
});
Window window = progressDialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.setGravity(Gravity.BOTTOM);
progressDialog.show();
}
progressText.setText(text);
progressBar.setProgress(percent);
Et c'est la mise en page de cette boîte de dialogue:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progressDialog"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerVertical="true">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="18sp"
android:padding="10dp"
android:text="@string/progress_title"/>
<LinearLayout android:id="@+id/progressDialog"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="10dp"
android:layout_centerVertical="true">
<ProgressBar android:id="@+id/progressBar"
android:layout_width="150dp"
android:layout_height="34dp"
android:paddingRight="10dp"
android:max="100"
android:progress="0"
android:fadingEdge="vertical"
style="?android:attr/progressBarStyleHorizontal"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/progressText"
android:paddingRight="10dp"/>
<Button android:layout_height="40dp"
android:layout_width="80dp"
android:id="@+id/btnCancel"
android:text="@string/dialog_cancel"/>
</LinearLayout>
</LinearLayout>
Autres conseils
il suffit d'ajouter FLAG_NOT_TOUCH_MODAL drapeau à votre boîte de dialogue
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Ma mise en œuvre qui était un peu plus hackish mais permet également appuyer sur des boutons d'être pris par la fenêtre d'arrière-plan
_wm = this.getWindowManager();
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
_view = layoutInflater.inflate(R.layout.notification, null);
_params = new WindowManager.LayoutParams();
_params.height = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
_params.width = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
_params.flags =
// this is to keep button presses going to the background window
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
// background transparant
_params.format = PixelFormat.TRANSLUCENT;
_gravity = Gravity.TOP;//Gravity.BOTTOM;
_wm.addView(_view, _params);