Android: come creare una finestra di dialogo senza titolo?


269

Sto cercando di generare una finestra di dialogo personalizzata in Android. Creo la mia finestra di dialogo in questo modo:

dialog = new Dialog(this);
dialog.setContentView(R.layout.my_dialog);

Tutto funziona benissimo tranne il titolo della finestra di dialogo. Anche se non imposto il titolo della finestra di dialogo, il popup della finestra di dialogo presenta uno spazio vuoto nella posizione della finestra di dialogo.

C'è un modo per nascondere questa parte della finestra di dialogo?

L'ho provato con un AlertDialog ma sembra che il layout non sia impostato correttamente:

LayoutInflater inflater = 
    (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.map_dialog, null);

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(view);

// dialog = new Dialog(this);
// dialog.setContentView(R.layout.map_dialog);

dialog = builder.create();

((TextView) dialog.findViewById(R.id.nr)).setText(number);

Se uso questo codice ottengo un'eccezione puntatore null nell'ultima riga. La finestra di dialogo non è nulla, quindi TextView che provo a recuperare non esiste.
Se decomprimere la parte in cui utilizzo Dialog Constructor tutto funziona bene, ma per il titolo sopra il layout della mia finestra di dialogo.


7
@Janusz rechoose la risposta a stackoverflow.com/a/3407871/632951
Pacerier

prova stackoverflow.com/questions/6263639/… invece della risposta precedente ... risposta semplice
Mohammed mansoor

Basta non chiamare AlertDialog.Builder.setTitle () e la finestra di dialogo apparirà senza un titolo.
Marvatron,

Risposte:


208

Puoi nascondere il titolo di una finestra di dialogo usando:

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


Versione precedente di questa risposta, che è troppo complicata:

Devi usare un AlertDialog. C'è una buona spiegazione sul sito dello sviluppatore Android sulle finestre di dialogo personalizzate .

In un breve riassunto, lo fai con un codice come copiato di seguito dal sito ufficiale. Questo prende un file layot ​​personalizzato, lo gonfia, gli fornisce un testo e un'icona di base, quindi lo crea. Lo mostreresti allora con alertDialog.show().

AlertDialog.Builder builder;
AlertDialog alertDialog;

Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater)
        mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
        (ViewGroup) findViewById(R.id.layout_root));

TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);

builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();

In risposta al commento:

Presumo che TextView con l'id nrsia nella vista con cui si sta gonfiando View view = inflater..... Se è così, allora devi cambiare solo un po ': invece di dialog.findView...farlo view.findView.... Quindi, una volta terminato, ricordati di usare dialog.show () o persino builder.show () senza preoccuparti di fare builder.create ().


4
Penso che potresti aver letto male la domanda? Janusz ha già visualizzato la finestra di dialogo personalizzata e richiede solo informazioni sulla rimozione del titolo
Donal Rafferty,

17
Bene, secondo la documentazione ufficiale, "Una finestra di dialogo creata con la classe Dialog di base deve avere un titolo. Se non si chiama setTitle (), lo spazio utilizzato per il titolo rimane vuoto, ma ancora visibile. Se non si ' non vuoi affatto un titolo, quindi devi creare la tua finestra di dialogo personalizzata usando la classe AlertDialog. " Non l'ho provato personalmente, ma ciò suggerirebbe che anche usando un layout di dialogo personalizzato o temi, è impossibile rimuovere lo spazio del titolo.
Steve Haley,

2
Secondo pensiero: penso che stiamo capendo il "titolo" in modo diverso. Suppongo che stia parlando dello spazio nella parte superiore della finestra a comparsa, non del titolo nella parte superiore dell'app.
Steve Haley,

11
@SteveHaley, No è ​​possibile nasconderlo usando la seguente rigadialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Sami Eltamawy

1
Assicurati di fare dialog.requestWindowFeature (Window.FEATURE_NO_TITLE); PRIMA di gonfiare la vista della finestra di dialogo.
Alexey Podlasov,

585

FEATURE_NO_TITLE funziona quando si crea una finestra di dialogo da zero, come in:

Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

Ma non funziona quando si crea un AlertDialog (o si usa il Builder), perché disabilita già il titolo e ne usa uno personalizzato internamente.

Ho esaminato le fonti dell'SDK e penso che non possa essere risolto. Quindi, per rimuovere la spaziatura superiore, l'unica soluzione è creare una finestra di dialogo personalizzata da zero IMO, utilizzando direttamente la classe Dialog.

Inoltre, è possibile farlo con uno stile, ad esempio in styles.xml:

<style name="FullHeightDialog" parent="android:style/Theme.Dialog">
   <item name="android:windowNoTitle">true</item>
</style>

E poi:

Dialog dialog = new Dialog(context, R.style.FullHeightDialog);

Invece di creare una finestra di dialogo personalizzata da zero, ho creato styles.xml come suggerito da oliverg. E poi, ho aggiunto android: theme = "@ style / FullHeightDialog" alla dichiarazione <activity> ... </acitivity> nel file Manifest. Ha appena funzionato. Grazie ..
Indrajeet,

@olivierg ma voglio un pulsante con una finestra di dialogo a tutta altezza. qual è la soluzione?
Pacerier,

1
Si noti che la richiesta della rigaWindowFeature deve essere PRIMA della riga setContentView.
Fattie,

Mentre questo risponde meglio ai commenti reali, la soluzione nella risposta accettata è la migliore secondo me. Ho iniziato a farlo in questo modo, con un approccio pulito Dialog, ma crearne uno è AlertDialogstato molto più semplice. Come si afferma nei documenti : The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead, use one of the following subclasses: <AlertDialog and others described here>. La AlertDialoggestisce anche roba del ciclo di vita e OK / Cancel nella disinvoltura.
Krøllebølle,

67

Nel tuo codice aggiungi questa riga

requestWindowFeature(Window.FEATURE_NO_TITLE);  

O in XML usa un tema

android:theme="@android:style/Theme.NoTitleBar"

XML sarebbe un'implementazione migliore in quanto con la versione del codice viene creata e quindi rimossa la barra del titolo che è uno spreco di risorse

Ok buon tentativo ma non funziona. Ottengo: android.view.WindowManager $ BadTokenException: impossibile aggiungere la finestra - token null non è per un'applicazione se voglio chiudere la finestra di dialogo.

Cambia il tipo di finestra di avviso in finestra di sistema (ad es. TYPE_SYSTEM_OVERLAY) e verifica se il problema è stato risolto


2
Non chiamare setContentView () prima di requestFeature ().
jlopez,

61

Usa così:

Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 

Ciò rimuoverà qualsiasi barra del titolo dalla finestra di dialogo.


3
Non chiamare setContentView () prima di requestFeature ().
jlopez,

2
Come posso riportarlo più tardi?
sviluppatore Android

58

Utilizzare sotto il codice prima di setcontentview: -

    Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    dialog.setContentView(R.layout.custom_dialog);

Nota : è necessario disporre del codice sopra, nello stesso ordine e riga. requestWindowFeaturedeve essere prima della riga setContentView.


Quando si utilizza in un dialogo, questa soluzione funziona meglio per me poiché la risposta accettata crea un piccolo spazio verticale tra la cornice del dialogo e la vista del contenuto interno.
Sebastian Roth,

38

puoi rimuovere il titolo di

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

dove dialog è il nome del mio dialog.


Non chiamare setContentView () prima di requestFeature ()
jlopez

29

Nel tuo codice, se usi, requestWindowFeature(Window.FEATURE_NO_TITLE); assicurati che vada prima dialog.setContentView();altrimenti causerebbe il crash dell'applicazione.


piuttosto dubito di provare prima e abbastanza sorpreso che ovviamente funzioni. poiché in android.developer.com hanno affermato chiaramente che è necessario che un dialogo personalizzato abbia un titolo. : P
richardlin,

10

Ho trovato Three Way per fare questo>

1) Utilizzo di requestWindowFeature

Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(dialog.getWindow().FEATURE_NO_TITLE); 

2) Uso dello stile (style.xml)

<style name="FullHeightDialog" parent="android:style/Theme.Dialog">
   <item name="android:windowNoTitle">true</item>
</style>

Dialog dialog = new Dialog(context, R.style.FullHeightDialog);

3) Utilizzo del tema XML in AndroidManifest.xml

 android:theme="@android:style/Theme.NoTitleBar"

1
Il metodo 1 dovrebbe essere dialog.requestWindowFeature (Window.FEATURE_NO_TITLE);
Jon Willis,

10

Nella tua classe Custom_Dialog.java aggiungi requestWindowFeature(Window.FEATURE_NO_TITLE)

public class Custom_Dialog extends Dialog {

    protected Custom_Dialog(Context context, int theme) {
        super(context, theme);
        // TODO Auto-generated constructor stub
        requestWindowFeature(Window.FEATURE_NO_TITLE); //This line 
    }
}

Questa è l'unica cosa che ha funzionato per me ... per qualche motivo tutti gli altri suggerimenti non hanno funzionato. L'unica cosa che consiglierei è di rendere pubblico il costruttore e anche di fornire l'altro costruttore Dialog che prende solo un contesto
Giustino

7

la risposta di olivierg funzionato per me ed è la soluzione migliore se creare una classe Dialog personalizzata è la strada che vuoi seguire. Tuttavia, mi dava fastidio non poter usare la classe AlertDialog. Volevo essere in grado di utilizzare lo stile AlertDialog predefinito del sistema. La creazione di una classe di dialogo personalizzata non avrebbe questo stile.

Quindi ho trovato una soluzione (hack) che funzionerà senza dover creare una classe personalizzata, è possibile utilizzare i costruttori esistenti.

AlertDialog mette una vista sopra la vista del contenuto come segnaposto per il titolo. Se trovi la vista e imposti l'altezza su 0, lo spazio scompare.

Ho provato questo su 2.3 e 3.0 finora, è possibile che non funzioni ancora su tutte le versioni.

Ecco due metodi di supporto per farlo:

/**
 * Show a Dialog with the extra title/top padding collapsed.
 * 
 * @param customView The custom view that you added to the dialog
 * @param dialog The dialog to display without top spacing
     * @param show Whether or not to call dialog.show() at the end.
 */
public static void showDialogWithNoTopSpace(final View customView, final Dialog dialog, boolean show) {
    // Now we setup a listener to detect as soon as the dialog has shown.
    customView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // Check if your view has been laid out yet
            if (customView.getHeight() > 0) {
                // If it has been, we will search the view hierarchy for the view that is responsible for the extra space. 
                LinearLayout dialogLayout = findDialogLinearLayout(customView);
                if (dialogLayout == null) {
                    // Could find it. Unexpected.

                } else {
                    // Found it, now remove the height of the title area
                    View child = dialogLayout.getChildAt(0);
                    if (child != customView) {
                        // remove height
                        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
                        lp.height = 0;
                        child.setLayoutParams(lp);

                    } else {
                        // Could find it. Unexpected.
                    }
                }

                // Done with the listener
                customView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
         }

    });

    // Show the dialog
    if (show)
             dialog.show();
}

/**
 * Searches parents for a LinearLayout
 * 
 * @param view to search the search from
 * @return the first parent view that is a LinearLayout or null if none was found
 */
public static LinearLayout findDialogLinearLayout(View view) {
    ViewParent parent = (ViewParent) view.getParent();
    if (parent != null) {
        if (parent instanceof LinearLayout) {
            // Found it
            return (LinearLayout) parent;

        } else if (parent instanceof View) {
            // Keep looking
            return findDialogLinearLayout((View) parent);

        }
    }

    // Couldn't find it
    return null;
}

Ecco un esempio di come viene utilizzato:

    Dialog dialog = new AlertDialog.Builder(this)
        .setView(yourCustomView)
        .create();

    showDialogWithNoTopSpace(yourCustomView, dialog, true);

Se lo stai usando con un DialogFragment, sostituisci il DialogFragment onCreateDialog metodo . Quindi crea e restituisci la finestra di dialogo come nel primo esempio sopra. L'unica modifica è che dovresti passare false come terzo parametro (show) in modo che non chiami show () nella finestra di dialogo. DialogFragment lo gestirà in seguito.

Esempio:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = new AlertDialog.Builder(getContext())
        .setView(yourCustomView)
        .create();

    showDialogWithNoTopSpace(yourCustomView, dialog, false);
    return dialog;
}

Mentre lo testerò ulteriormente, sarò sicuro di aggiornare con eventuali modifiche aggiuntive necessarie.


Soluzione elegante, +1. Sai come usarlo in un DialogFragment?
Binoy Babu,

@Binoy ha aggiornato la risposta per DialogFragments (in realtà è così che lo uso personalmente)
cottonBallPaws

6

Non so se questa domanda sia ancora attuale, ma nel mio caso, quando sono passato da Dialog a DialogFragment,

requestWindowFeature(Window.FEATURE_NO_TITLE);

non era un'opzione, ma potevo usare

setStyle(STYLE_NO_TITLE, 0);

invece con lo stesso risultato.


Per chiarire, questa linea ( setStyle(STYLE_NO_TITLE, 0);) andrà nel metodo onCreate della tua classe DialogFragment.
Prezzo

4

Imposta il titolo su stringa vuota usando il builder.

    Builder builder = new AlertDialog.Builder(context);
    builder.setTitle("");
...
    builder.show();

3

imposta l'attributo "gravità" sull'intera finestra di dialogo su "centro". Quindi dovrai sovrascrivere quell'impostazione su tutti i componenti figlio nella finestra di dialogo che non vuoi centrare.


3
dialog=new Dialog(YourActivity.this, 1);  // to make dialog box full screen with out title.
dialog.setContentView(layoutReference);
dialog.setContentView(R.layout.layoutexample);

3

in XML usa un tema

android:theme="@android:style/Theme.NoTitleBar"

3

Se usiamo semplicemente la finestra di dialogo senza il setTitle(), allora funzionerà per rimuovere lo spazio del titolo?

mUSSDDialog = new AlertDialog.Builder(context).setView(dialogView)
.setPositiveButton(R.string.send_button,DialogListener)
.setNegativeButton(R.string.cancel,DialogListener)
.setCancelable(false).create();

3

Pensi di poterlo usare ora:

AlertDialog dialog = new AlertDialog.Builder(this)
  .setView(view)
  .setTitle("")
  .create()

2
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", 
                             "Loading. Please wait...", true);

crea una finestra di dialogo meno titolo


2
public static AlertDialog showAlertDialogWithoutTitle(Context context,String msg) 
     {
      AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
      alertDialogBuilder.setMessage(msg).setCancelable(false)
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int id) {

         }
        });

       return alertDialogBuilder.create(); 
     }

2

Durante l'utilizzo di AlertDialog, il non utilizzo setTitle()fa scomparire il titolo


1

Dopo un sacco di hacking, ho ottenuto questo per funzionare:

            Window window = dialog.getWindow();
            View view = window.getDecorView();
            final int topPanelId = getResources().getIdentifier( "topPanel", "id", "android" );
            LinearLayout topPanel = (LinearLayout) view.findViewById(topPanelId);
            topPanel.setVisibility(View.GONE);

quello che è dialogqui egetResources()
Kartheek s

1

Puoi farlo senza usare AlertDialogdefinendo la nuova Classe che si estende dalla DialogClasse in questo modo:

public class myDialog extends Dialog {
    public myDialog(Context context) {
        super(context);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    }
}

1

Ecco qualcosa che puoi fare AlertBuilderper far scomparire il titolo:

TextView title = new TextView(this);
title.setVisibility(View.GONE);
builder.setCustomTitle(title);

1

Usa questo

    Dialog dialog = new Dialog(getActivity());
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    dialog.setCancelable(true);
    dialog.setContentView(R.layout.image_show_dialog_layout);

0

dialog_custom .requestWindowFeature (Window.FEATURE_NO_TITLE);

questo rimuoverà il titolo dalla finestra di dialogo.

Nota aggiungi queste righe prima di aggiungere contenuti .. per es

     dialog_custom = Dialog(activity!!)
    dialog_custom.requestWindowFeature(Window.FEATURE_NO_TITLE)
    dialog_custom.setContentView(R.layout.select_vehicle_type)
    dialog_custom.setCanceledOnTouchOutside(false)
    dialog_custom.setCancelable(true)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.