Android: как создать диалог без заголовка?

269

Я пытаюсь создать собственный диалог в Android. Я создаю свой диалог так:

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

Все работает хорошо, за исключением названия диалога. Даже если я не установлю заголовок диалога, всплывающее окно диалога будет содержать пустое место в позиции диалога.

Есть ли способ скрыть эту часть диалога?

Я пробовал это с AlertDialog, но кажется, что макет не установлен должным образом:

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

Если я использую этот код, я получаю нулевое исключение указателя в последней строке. Диалог не является нулевым, поэтому TextView, который я пытаюсь получить, не существует.
Если я раскомментирую часть, в которой я использую конструктор диалогов, все будет хорошо, но для заголовка над моим диалоговым макетом.

Януш
источник
7
@Janusz выберите свой ответ для stackoverflow.com/a/3407871/632951
Pacerier
попробуйте stackoverflow.com/questions/6263639/… вместо предыдущего ответа ... простой ответ
Мухаммед Мансур
Только не вызывайте AlertDialog.Builder.setTitle (), и ваш диалог появится без заголовка.
Марватрон

Ответы:

208

Вы можете скрыть заголовок диалога, используя:

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


Предыдущая версия этого ответа, которая слишком сложна:

Вам нужно использовать AlertDialog. На сайте разработчика Android есть хорошее объяснение о пользовательских диалогах .

В кратком изложении вы делаете это с помощью кода, скопированного ниже с официального сайта. Это берет пользовательский файл layot, раздувает его, дает ему некоторый основной текст и значок, а затем создает его. Вы бы показали это тогда с 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();

В ответ на комментарий:

Я предполагаю, что TextView с идентификатором nrнаходится в представлении, которым вы надуваетесь View view = inflater..... Если это так, то вам нужно изменить только один бит: вместо того, dialog.findView...чтобы сделать это view.findView.... Затем, как только вы это сделаете, не забудьте использовать dialog.show () или даже builder.show (), не удосужившись сделать builder.create ().

Стив Хейли
источник
4
Я думаю, что вы, возможно, неправильно прочитали Вопрос? У Януша уже есть настраиваемое диалоговое окно, и ему просто требуется информация об удалении заголовка
Донал Рафферти
17
Что ж, согласно официальной документации: «Диалог, созданный с помощью базового класса Dialog, должен иметь заголовок. Если вы не вызываете setTitle (), пространство, используемое для заголовка, остается пустым, но все еще видимым. Если вы не Если вам вообще не нужен заголовок, вам следует создать свой собственный диалог, используя класс AlertDialog. " Я лично не экспериментировал с этим, но это наводит на мысль, что даже используя пользовательский макет диалога или темы, невозможно удалить пространство заголовка.
Стив Хейли
2
Вторая мысль: я думаю, что мы понимаем «название» по-другому. Я предполагаю, что он говорит о месте в верхней части всплывающего окна, а не о заголовке в верхней части приложения.
Стив Хейли
11
@ SteveHaley, Нет, это можно скрыть, используя следующую строкуdialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Сами Эльтамави,
1
Убедитесь, что вы делаете dialog.requestWindowFeature (Window.FEATURE_NO_TITLE); ПЕРЕД тем, как вы завышаете свой диалог.
Алексей Подласов
585

FEATURE_NO_TITLE работает при создании диалога с нуля, как в:

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

Но он не работает при создании AlertDialog (или при использовании Builder), потому что он уже отключает заголовок и использует собственный внутри.

Я посмотрел на источники SDK, и я думаю, что это не может быть обойти. Таким образом, чтобы удалить верхний интервал, единственное решение состоит в том, чтобы создать пользовательский диалог с нуля IMO, используя класс Dialog напрямую.

Также это можно сделать с помощью стиля, например, в styles.xml:

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

А потом:

Dialog dialog = new Dialog(context, R.style.FullHeightDialog);
olivierg
источник
Вместо создания собственного диалога с нуля, я создал файл styles.xml, предложенный oliverg. И затем я добавил android: theme = "@ style / FullHeightDialog" в объявление <activity> ... </ acitivity> в файле манифеста. Это просто сработало. Спасибо ..
Индраджит
@olivierg, но я хочу кнопку с диалогом полной высоты. какое решение?
Pacerier
1
Обратите внимание, что строка requestWindowFeature должна быть ДО строки setContentView.
Толстяк
Хотя это лучше всего отвечает фактическим комментариям, на мой взгляд, решение в принятом ответе является лучшим. Я начал делать это так, с чистым Dialog, но создание AlertDialogбыло намного проще. Как указано в документации : 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>. AlertDialogТакже обрабатывает жизненный цикл вещь и нормально / отменить в простом манере.
Krøllebølle
67

В своем коде добавьте эту строку

requestWindowFeature(Window.FEATURE_NO_TITLE);  

Или в XML используйте тему

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

XML будет лучшей реализацией, так как с версией кода строка заголовка создается, а затем удаляется, что является пустой тратой ресурсов.

Хорошо, хорошая попытка, но она не работает. Я получаю: android.view.WindowManager $ BadTokenException: Невозможно добавить окно - нулевой токен не для приложения, если я хочу показать диалоговое окно.

Измените тип диалога предупреждения на системный диалог (например, TYPE_SYSTEM_OVERLAY) и посмотрите, решит ли это вашу проблему

Донал Рафферти
источник
2
Не вызывайте setContentView () перед requestFeature ().
Jlopez
61

Используйте как это:

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

Это удалит любую строку заголовка из диалогового окна.

алок тивари
источник
3
Не вызывайте setContentView () перед requestFeature ().
Jlopez
2
Как мне вернуть его позже?
Android-разработчик
58

Используйте код ниже setcontentview: -

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

Примечание : Вы должны иметь вышеуказанный код в том же порядке и строке. requestWindowFeatureдолжен быть перед строкой setContentView.

Дуггу
источник
При использовании в Dialogfragment это решение работает лучше для меня, поскольку принятый ответ создает крошечный вертикальный разрыв между рамкой диалога и внутренним представлением содержимого.
Себастьян Рот
38

Вы можете удалить заголовок с помощью

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

где диалог - это имя моего диалога.

Шайлендра
источник
Не вызывайте setContentView () перед requestFeature ()
jlopez
29

В вашем коде, если вы используете requestWindowFeature(Window.FEATURE_NO_TITLE); , убедитесь, что он идет раньше, dialog.setContentView();иначе это вызывает сбой приложения.

Шимон Моравский
источник
скорее сомневаюсь попробовать раньше и совсем удивляюсь что это явно работает. так как в android.developer.com они ясно сказали, что для пользовательского диалога должен быть заголовок. : P
Ричардлин
10

Я нашел Три способа сделать это>

1) Использование requestWindowFeature

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

2) Использование стиля (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) Использование темы XML в AndroidManifest.xml

 android:theme="@android:style/Theme.NoTitleBar"
Нирав Ранпара
источник
1
Метод один должен быть dialog.requestWindowFeature (Window.FEATURE_NO_TITLE);
Джон Уиллис
10

В свой класс Custom_Dialog.java добавьте 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
источник
Это единственное, что сработало для меня ... почему-то все остальные предложения не сработали. Единственное, что я бы порекомендовал, - это сделать конструктор общедоступным, а также предоставить другой конструктор Dialog, который принимает только контекст
Justin
7

ответ оливьера сработал для меня и является лучшим решением, если вы хотите создать собственный класс Dialog. Однако меня беспокоило, что я не могу использовать класс AlertDialog. Я хотел иметь возможность использовать системный стиль AlertDialog по умолчанию. Создание пользовательского диалогового класса не будет иметь этот стиль.

Поэтому я нашел решение (взломать), которое будет работать без создания собственного класса, вы можете использовать существующие сборщики.

AlertDialog помещает представление над представлением содержимого в качестве заполнителя для заголовка. Если вы найдете вид и установите высоту 0, пространство исчезнет.

До сих пор я проверял это на 2.3 и 3.0, возможно, это работает не на всех версиях.

Вот два вспомогательных метода для этого:

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

Вот пример того, как это используется:

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

    showDialogWithNoTopSpace(yourCustomView, dialog, true);

Если вы используете это с DialogFragment, переопределите метод DialogFragment onCreateDialog. Затем создайте и верните диалог, как в первом примере выше. Единственное изменение заключается в том, что вы должны передать false в качестве третьего параметра (show), чтобы он не вызывал show () в диалоговом окне. DialogFragment будет обрабатывать это позже.

Пример:

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

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

По мере дальнейшего тестирования я обязательно обновлюсь с необходимыми дополнительными настройками.

cottonBallPaws
источник
Элегантное решение, +1. Знаете ли вы, как использовать это в DialogFragment?
Биной ​​Бабу
@Binoy обновил ответ для DialogFragments (именно так я и использую его лично)
cottonBallPaws
6

Я не знаю, актуален ли этот вопрос, но в моем случае, когда я переключился с Dialog на DialogFragment,

requestWindowFeature(Window.FEATURE_NO_TITLE);

был не вариант, но я мог бы использовать

setStyle(STYLE_NO_TITLE, 0);

вместо этого с тем же результатом.

Analizer
источник
Чтобы уточнить, эта строка ( setStyle(STYLE_NO_TITLE, 0);) будет идти в метод onCreate вашего класса DialogFragment.
Цена
4

Установите заголовок для пустой строки, используя строитель.

    Builder builder = new AlertDialog.Builder(context);
    builder.setTitle("");
...
    builder.show();
Сере Дери
источник
3

установите атрибут "гравитация" во всем диалоге в "центр". Затем вам нужно будет переопределить эту настройку для всех дочерних компонентов в диалоге, который вы не хотите центрировать.

Matt
источник
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
источник
3

в XML используй тему

android:theme="@android:style/Theme.NoTitleBar"
Асад Рао
источник
3

Если мы просто используем диалоговое окно без setTitle(), тогда это сработает при удалении пробела?

mUSSDDialog = new AlertDialog.Builder(context).setView(dialogView)
.setPositiveButton(R.string.send_button,DialogListener)
.setNegativeButton(R.string.cancel,DialogListener)
.setCancelable(false).create();
JAD
источник
3

Думаю, вы можете просто использовать это сейчас:

AlertDialog dialog = new AlertDialog.Builder(this)
  .setView(view)
  .setTitle("")
  .create()
J2K
источник
2
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", 
                             "Loading. Please wait...", true);

создает диалог без заголовка

Правин Кондапалли
источник
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

При использовании AlertDialog неиспользование setTitle()заставляет заголовок исчезать

kostikus
источник
1

После нескольких взломов, я получил это на работу:

            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);
Чак Д
источник
что dialogздесь иgetResources()
Kartheek s
1

Вы можете сделать это без использования AlertDialog, определив новый класс, который выходит из Dialogкласса следующим образом:

public class myDialog extends Dialog {
    public myDialog(Context context) {
        super(context);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    }
}
Халед АбуШкир
источник
1

Вот что вы можете сделать, AlertBuilderчтобы название исчезло:

TextView title = new TextView(this);
title.setVisibility(View.GONE);
builder.setCustomTitle(title);
rundavidrun
источник
1

Использовать это

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

это удалит заголовок из диалога cutsom.

Примечание: добавьте эти строки перед добавлением контента. Например,

     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)
Индраджит Джиоти
источник