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.