Android: jak utworzyć okno dialogowe bez tytułu?

269

Próbuję wygenerować niestandardowe okno dialogowe w systemie Android. Moje okno dialogowe tworzę w następujący sposób:

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

Wszystko działa dobrze, z wyjątkiem tytułu Dialogu. Nawet jeśli nie ustawię tytułu okna dialogowego, w oknie dialogowym jest puste miejsce w pozycji okna dialogowego.

Czy jest jakiś sposób, aby ukryć tę część okna dialogowego?

Próbowałem z AlertDialog, ale wygląda na to, że układ nie jest ustawiony poprawnie:

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

Jeśli użyję tego kodu, w ostatnim wierszu zostanie wyświetlony zerowy wyjątek wskaźnika. Okno dialogowe nie ma wartości NULL, więc TextView, który próbuję pobrać, nie istnieje.
Jeśli odkomentuję część, w której korzystam z Konstruktora dialogu, wszystko działa dobrze, ale dla tytułu powyżej mojego układu okna dialogowego.

Janusz
źródło
7
@Janusz ponownie wybierz odpowiedź na stackoverflow.com/a/3407871/632951
Pacerier
spróbuj stackoverflow.com/questions/6263639/... zamiast poprzedniej odpowiedzi ... prosta odpowiedź
Mohammed mansoor
Po prostu nie wywoływaj AlertDialog.Builder.setTitle (), a okno dialogowe pojawi się bez tytułu.
marvatron

Odpowiedzi:

208

Możesz ukryć tytuł okna dialogowego, używając:

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


Poprzednia wersja tej odpowiedzi, która jest nadmiernie skomplikowana:

Musisz użyć AlertDialog. Istnieje dobre wyjaśnienie na stronie programisty Androida na temat niestandardowych okien dialogowych .

Krótko mówiąc, robisz to za pomocą kodu takiego jak skopiowany poniżej z oficjalnej strony. To bierze niestandardowy plik layot, napompowuje go, daje mu podstawowy tekst i ikonę, a następnie tworzy. Pokazałbyś to wtedy za pomocą 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();

W odpowiedzi na komentarz:

Zakładam, że TextView z identyfikatorem nrznajduje się w widoku, który nadmuchujesz View view = inflater..... Jeśli tak, to musisz zmienić tylko jeden bit: zamiast dialog.findView...zrobić view.findView.... Potem, kiedy to zrobisz, pamiętaj, aby użyć dialog.show (), a nawet builder.show (), nie zawracając sobie głowy wykonaniem builder.create ().

Steve Haley
źródło
4
Myślę, że mogłeś źle odczytać Pytanie? Janusz ma już wyświetlane niestandardowe okno dialogowe i wymaga jedynie informacji o usunięciu tytułu
Donal Rafferty
17
Cóż, zgodnie z oficjalną dokumentacją: „Okno dialogowe wykonane z podstawową klasą Dialog musi mieć tytuł. Jeśli nie wywołasz setTitle (), wówczas miejsce użyte na tytuł pozostaje puste, ale nadal widoczne. Jeśli chcesz mieć tytuł, powinieneś utworzyć niestandardowe okno dialogowe za pomocą klasy AlertDialog. ” Nie eksperymentowałem z tym osobiście, ale to sugerowałoby, że nawet przy użyciu niestandardowego układu lub motywów okna dialogowego niemożliwe jest usunięcie przestrzeni tytułowej.
Steve Haley,
2
Druga myśl: myślę, że inaczej rozumiemy „tytuł”. Zakładam, że mówi o miejscu w górnej części wyskakującego okienka, a nie o tytule w górnej części aplikacji.
Steve Haley
11
@ SteveHaley, Nie, nie można tego ukryć, używając następującego wierszadialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Sami Eltamawy
1
Upewnij się, że wykonujesz dialog.requestWindowFeature (Window.FEATURE_NO_TITLE); PRZED nadmuchaniem widoku okna dialogowego.
Aleksiej Podlasow
585

FEATURE_NO_TITLE działa podczas tworzenia okna dialogowego od zera, jak w:

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

Ale to nie działa podczas tworzenia AlertDialog (lub przy użyciu Konstruktora), ponieważ już wyłącza tytuł i używa niestandardowego wewnętrznie.

Przejrzałem źródła SDK i myślę, że nie można tego obejść. Aby więc usunąć górne odstępy, jedynym rozwiązaniem jest utworzenie niestandardowego okna dialogowego od podstaw IMO, bezpośrednio za pomocą klasy Dialog.

Można to również zrobić za pomocą stylu, np. W styles.xml:

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

I wtedy:

Dialog dialog = new Dialog(context, R.style.FullHeightDialog);
olivierg
źródło
Zamiast tworzyć niestandardowe okno dialogowe od podstaw, stworzyłem styles.xml zgodnie z sugestią oliverg. A potem dodałem androida: theme = "@ style / FullHeightDialog" do deklaracji <activity> ... </aciency> w pliku Manifest. Po prostu zadziałało. Dzięki ..
Indrajeet,
@olivierg, ale chcę przycisk z oknem dialogowym pełnej wysokości. jakie jest rozwiązanie
Pacerier
1
Zwróć uwagę, że wiersz requestWindowFeature musi być PRZED wierszem setContentView.
Fattie
Chociaż najlepiej odpowiada to faktycznym komentarzom, moim zdaniem rozwiązanie w przyjętej odpowiedzi jest najlepsze. Zacząłem robić to w ten sposób, z czystym Dialog, ale tworzenie AlertDialogbyło znacznie łatwiejsze. Jak stwierdzono w docs : 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>. AlertDialogObsługuje również cyklem życia rzeczy i OK / Cancel w łatwy sposób.
Krøllebølle
67

W swoim kodzie dodaj ten wiersz

requestWindowFeature(Window.FEATURE_NO_TITLE);  

Lub w XML użyj motywu

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

XML byłby lepszą implementacją, ponieważ w wersji kodu pasek tytułu jest tworzony, a następnie usuwany, co jest marnotrawstwem zasobów

Dobra, spróbuj, ale to nie działa. Dostaję: android.view.WindowManager $ BadTokenException: Nie można dodać okna - token null nie jest przeznaczony dla aplikacji, jeśli chcę włączyć okno dialogowe.

Zmień typ okna alertu na okno systemowe (np. TYPE_SYSTEM_OVERLAY) i sprawdź, czy to rozwiąże problem

Donal Rafferty
źródło
2
Nie wywoływaj setContentView () przed requestFeature ().
Jepez
61

Użyj w ten sposób:

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

Spowoduje to usunięcie paska tytułu z okna dialogowego.

alok tiwari
źródło
3
Nie wywoływaj setContentView () przed requestFeature ().
Jepez
2
Jak mogę go później przywrócić?
programista Androida
58

Użyj kodu poniżej setcontentview:

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

Uwaga : Musisz mieć powyższy kod, w tej samej kolejności i wierszu. requestWindowFeaturemusi znajdować się przed linią setContentView.

duggu
źródło
W przypadku korzystania z Dialogfragment to rozwiązanie działa dla mnie lepiej, ponieważ zaakceptowana odpowiedź tworzy niewielką pionową przerwę między ramką okna dialogowego a widokiem zawartości wewnętrznej.
Sebastian Roth
38

możesz usunąć tytuł przez

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

gdzie okno dialogowe to nazwa mojego okna dialogowego.

shailendra
źródło
Nie wywołuj setContentView () przed requestFeature ()
jlopez
29

Jeśli używasz kodu, requestWindowFeature(Window.FEATURE_NO_TITLE); upewnij się, że działa wcześniej, w dialog.setContentView();przeciwnym razie spowoduje to awarię aplikacji.

Szymon Morawski
źródło
raczej wątpliwości, aby spróbować wcześniej i dość zaskoczony, że to oczywiście działa. ponieważ w android.developer.com powiedzieli wyraźnie, że niestandardowe okno dialogowe musi mieć tytuł. : P
richardlin
10

Znalazłem Three Way to zrobić>

1) Korzystanie z requestWindowFeature

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

2) Korzystanie ze stylu (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) Używanie motywu XML w AndroidManifest.xml

 android:theme="@android:style/Theme.NoTitleBar"
Nirav Ranpara
źródło
1
Metodą pierwszą powinien być dialog.requestWindowFeature (Window.FEATURE_NO_TITLE);
Jon Willis,
10

W swojej klasie Custom_Dialog.java dodaj 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 
    }
}
M_K
źródło
To jedyna rzecz, która działała dla mnie ... z jakiegoś powodu wszystkie inne sugestie nie zadziałały. Jedyną rzeczą, którą chciałbym polecić jest, aby społeczeństwo konstruktora, a także w celu zapewnienia innego konstruktora dialogowym, które zajmie tylko kontekst
Justin
7

Odpowiedź olivierga zadziałała dla mnie i jest najlepszym rozwiązaniem, jeśli utworzenie niestandardowej klasy Dialog to trasa, którą chcesz się udać. Niepokoiło mnie jednak, że nie mogę użyć klasy AlertDialog. Chciałem móc korzystać z domyślnego systemu AlertDialog. Utworzenie niestandardowej klasy okna dialogowego nie miałoby tego stylu.

Więc znalazłem rozwiązanie (hack), które będzie działać bez konieczności tworzenia niestandardowej klasy, możesz użyć istniejących konstruktorów.

AlertDialog umieszcza widok nad widokiem zawartości jako symbol zastępczy tytułu. Jeśli znajdziesz widok i ustawisz wysokość na 0, przestrzeń zniknie.

Do tej pory przetestowałem to na 2.3 i 3.0, możliwe, że nie działa jeszcze w każdej wersji.

Oto dwie metody pomocnicze:

/**
 * 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;
}

Oto przykład jego użycia:

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

    showDialogWithNoTopSpace(yourCustomView, dialog, true);

Jeśli używasz tego z DialogFragment, zastąp onCreateDialogmetodę DialogFragment . Następnie utwórz i zwróć okno dialogowe jak w pierwszym przykładzie powyżej. Jedyną zmianą jest to, że powinieneś przekazać false jako trzeci parametr (show), aby nie wywoływał show () w oknie dialogowym. DialogFragment zajmie się tym później.

Przykład:

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

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

Gdy będę to testować dalej, będę musiał zaktualizować o wszelkie dodatkowe poprawki.

cottonBallPaws
źródło
Eleganckie rozwiązanie, +1. Czy wiesz, jak używać tego w DialogFragment?
Binoy Babu
@Binoy zaktualizował odpowiedź dla DialogFragments (tak właśnie ja osobiście jej używam)
cottonBallPaws
6

Nie wiem, czy to pytanie jest nadal aktualne, ale w moim przypadku, kiedy przełączyłem się z Dialog na DialogFragment,

requestWindowFeature(Window.FEATURE_NO_TITLE);

nie było opcji, ale mogłem użyć

setStyle(STYLE_NO_TITLE, 0);

zamiast tego z tym samym wynikiem.

Analizator
źródło
Aby to wyjaśnić, ta linia ( setStyle(STYLE_NO_TITLE, 0);) przejdzie do metody onCreate klasy DialogFragment.
Cena
4

Ustaw tytuł na pusty ciąg znaków za pomocą konstruktora.

    Builder builder = new AlertDialog.Builder(context);
    builder.setTitle("");
...
    builder.show();
Szere Dyeri
źródło
3

ustaw atrybut „grawitacja” w całym oknie dialogowym na „środek”. Następnie musisz zastąpić to ustawienie do wszystkich komponentów potomnych w oknie dialogowym, którego nie chcesz wyśrodkowywać.

Matt
źródło
3
dialog=new Dialog(YourActivity.this, 1);  // to make dialog box full screen with out title.
dialog.setContentView(layoutReference);
dialog.setContentView(R.layout.layoutexample);
Bamadeva
źródło
3

w XML użyj motywu

android:theme="@android:style/Theme.NoTitleBar"
Asad Rao
źródło
3

Jeśli po prostu skorzystamy z okna dialogowego bez setTitle(), to czy zadziała to w usunięciu spacji tytułu?

mUSSDDialog = new AlertDialog.Builder(context).setView(dialogView)
.setPositiveButton(R.string.send_button,DialogListener)
.setNegativeButton(R.string.cancel,DialogListener)
.setCancelable(false).create();
jad
źródło
3

Myślisz, że możesz tego teraz użyć:

AlertDialog dialog = new AlertDialog.Builder(this)
  .setView(view)
  .setTitle("")
  .create()
J2K
źródło
2
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", 
                             "Loading. Please wait...", true);

tworzy okno dialogowe bez tytułu

Praveen Kondapalli
źródło
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(); 
     }
Sandeep Kumar Patil
źródło
2

Podczas korzystania z AlertDialog nieużywanie setTitle()powoduje zniknięcie tytułu

kostikus
źródło
1

Po kilku włamaniach, mam to do pracy:

            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);
Chuck D.
źródło
co dialogtu jest igetResources()
Kartheek s
1

Możesz to zrobić bez użycia AlertDialog, definiując nową klasę, która wykracza poza Dialogklasę w następujący sposób:

public class myDialog extends Dialog {
    public myDialog(Context context) {
        super(context);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    }
}
Khaled AbuShqear
źródło
1

Oto coś, co możesz zrobić, AlertBuilderaby zniknął tytuł:

TextView title = new TextView(this);
title.setVisibility(View.GONE);
builder.setCustomTitle(title);
rundavidrun
źródło
1

Użyj tego

    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);
Habibur Rahman Ovie
źródło
0

dialog_custom .requestWindowFeature (Window.FEATURE_NO_TITLE);

spowoduje to usunięcie tytułu z okna dialogowego cutes.

Uwaga: dodaj tę linię przed dodaniem treści .. na przykład

     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)
indrajeet jyoti
źródło