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 rechoose свою відповідь на stackoverflow.com/a/3407871/632951
— Pacerier

спробуйте stackoverflow.com/questions/6263639/… замість попередньої відповіді… проста відповідь
— Мухаммед Мансур

Просто не дзвоніть на AlertDialog.Builder.setTitle (), і діалогове вікно з’явиться без заголовка.
— марватрон

Відповіді:


208

Ви можете приховати назву діалогового вікна, використовуючи:

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


Попередня версія цієї відповіді, яка є складною:

Вам потрібно скористатися AlertDialog. На сайті розробника Android є гарне пояснення щодо користувацьких діалогів .

Якщо дуже короткий підсумок, ви робите це з кодом, як скопійованим нижче з офіційного веб-сайту. Це бере власний файл лайот, надуває його, надає основний текст та значок, а потім створює його. Ви б потім це показали за допомогою 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
Я думаю, ви, можливо, неправильно прочитали питання? У Януша вже є спеціальне діалогове вікно і просто потрібна інформація про видалення заголовка
— Donal Rafferty

17
Отже, згідно з офіційною документацією, "Діалогове вікно, створене з базовим класом Dialog, повинно мати заголовок. Якщо ви не викликаєте setTitle (), то простір, який використовується для заголовка, залишається порожнім, але все ще видимим. Якщо ви цього не зробите" t взагалі не хочете заголовка, тоді вам слід створити власне діалогове вікно за допомогою класу AlertDialog. " Я особисто не експериментував з цим, але це дозволило б припустити, що навіть використовуючи спеціальний макет діалогу або теми, неможливо видалити пробіл заголовка.
— Стів Хейлі

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

Замість створення спеціального діалогового вікна з нуля я створив styles.xml, як запропонував oliverg. І тоді я додав андроїд: theme = "@ style / FullHeightDialog" до декларації <activity> ... </acibility> у файл Manifest. Це просто спрацювало. Дякую ..
— Indrajeet

@olivierg, але я хочу кнопку з діалоговим вікном на повну висоту. яке рішення?
— Pacerier

1
Зверніть увагу, що запит на рядокWindowFeature повинен бути ПЕРЕД лінією setContentView .
— Fattie

Хоча це найкраще відповідає фактичним коментарям, на мою думку, рішення у прийнятій відповіді є найкращим. Я почав робити це так, з чистого 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 () перед запитомFeature ().
— jlopez

61

Використовуйте так:

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

Це видалить будь-який рядок заголовка з діалогового вікна.


3
Не викликайте setContentView () перед запитомFeature ().
— jlopez

2
Як повернути його пізніше?
— андроїд розробник

58

Використовуйте код нижче перед setcontentview: -

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

Примітка . Ви повинні мати вищевказаний код у тому ж порядку та рядку. requestWindowFeatureмає бути перед рядком setContentView.


Під час використання в діалоговому фрагменті це рішення працює для мене краще, оскільки прийнята відповідь створює невеликий вертикальний проміжок між діалоговим кадром та внутрішнім видом вмісту.
— Себастьян Рот

38

ви можете видалити назву до

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

де діалог - це ім'я мого діалогу.


Не дзвоніть setContentView () перед запитомFeature ()
— jlopez

29

У своєму коді, якщо ви використовуєте, requestWindowFeature(Window.FEATURE_NO_TITLE); будьте впевнені, що це триває раніше, dialog.setContentView();інакше це призведе до збоїв у програмі.


швидше сумніваюся спробувати раніше і зовсім здивований, що це, очевидно, працює. оскільки в android.developer.com вони чітко сказали, що в користувальницькому діалоговому вікні має бути заголовок. : P
— richardlin

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

Це єдине, що працювало на мене ... чомусь усі інші пропозиції не спрацювали. Єдине, що я рекомендував би - зробити цей конструктор загальнодоступним, а також надати інший конструктор Dialog, який займає лише контекст
— Джастін

7

Відповідь olivierg працювала для мене і є найкращим рішенням, якщо створення власного класу 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, замініть onCreateDialogметод DialogFragment . Потім створіть і поверніть своє діалогове вікно, як перший приклад вище. Єдина зміна полягає в тому, що ви повинні передавати false як 3-й параметр (show), щоб він не викликав show () у діалоговому вікні. ДіалогFragment вирішить це пізніше.

Приклад:

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

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

Оскільки я тестую це далі, я обов'язково буду оновлювати всі необхідні додаткові налаштування.


Елегантне рішення, +1. Чи знаєте ви, як це використовувати в DialogFragment?
— Біной Бабу

@Binoy оновив відповідь на DialogFragments (саме так я особисто це використовую)
— cottonBallPaws

6

Я не знаю, чи все-таки це питання актуальне, але в моєму випадку, коли я перейшов з Dialog на DialogFragment,

requestWindowFeature(Window.FEATURE_NO_TITLE);

не був варіантом, але я міг використати

setStyle(STYLE_NO_TITLE, 0);

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


Для уточнення цей рядок ( setStyle(STYLE_NO_TITLE, 0);) перейде в метод onCreate класу DialogFragment.
— Ціна

4

Встановіть заголовок на порожній рядок за допомогою builder.

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

3

встановіть атрибут "gravity" у всьому діалоговому вікні на "center". Тоді вам потрібно буде замінити це налаштування для всіх дочірніх компонентів у діалоговому вікні, яке не хочете в центрі.


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

Якщо ми просто використаємо діалогове вікно без цього setTitle(), то чи буде це працювати у видаленні пробілу заголовка?

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

3

Подумайте, ви можете просто використовувати це зараз:

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


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()заголовок зникає


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

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

це видалить заголовок із діалогового вікна.

Зауважте, додайте цей рядок перед додаванням вмісту

     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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.