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

如果使用此代码,则在最后一行中将获得空的Pointer Exception。该对话框不为null,因此我尝试检索的TextView不存在。
如果取消注释使用“对话构造器”的部分,则一切正常,但对话框布局上方的标题除外。



尝试stackoverflow.com/questions/6263639/…而不是以前的答案...简单的答案
Mohammed mansoor

只是不要调用AlertDialog.Builder.setTitle(),您的对话框将没有标题出现。
marvatron

Answers:


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

回应评论:

我假设ID nr为id的TextView 位于您要夸大的View中View view = inflater....。如果是这样,那么你需要改变只是一个位:不是dialog.findView...让它view.findView...。然后,一旦完成该操作,请记住使用dialog.show()甚至builder.show(),而不必费心去执行builder.create()。


4
我认为您可能看错了问题?Janusz已经显示了自定义对话框,只需要有关删除标题的信息
Donal Rafferty

17
好吧,根据官方文档,“使用Dialog基类创建的对话框必须具有标题。如果不调用setTitle(),则用于标题的空间将保持空白,但仍然可见。根本不需要标题,那么您应该使用AlertDialog类创建自定义对话框。” 我没有亲自进行过尝试,但这表明即使使用自定义对话框布局或主题,也无法删除标题空间。
史蒂夫·哈利

2
第二个想法:我认为我们对“标题”的理解有所不同。我认为他是在谈论弹出窗口顶部的空间,而不是应用程序顶部的标题。
史蒂夫·海利

11
@SteveHaley,不,可以使用以下行隐藏它dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Sami Eltamawy 2014年

1
确保您执行dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 在您增加对话框视图之前。
Alexey Podlasov

585

从头开始创建对话框时,FEATURE_NO_TITLE可以工作,如下所示:

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

但是在创建AlertDialog(或使用Builder)时它不起作用,因为它已禁用标题并在内部使用自定义标题。

我看过SDK的来源,但我认为它无法解决。因此,要删除顶部间距,唯一的解决方案是直接使用Dialog类从头开始创建IMO自定义对话框。

同样,可以使用一种样式来做到这一点,例如在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);

我没有从头开始创建自定义对话框,而是按照Oliverg的建议创建了styles.xml。然后,我在清单文件中的<activity> ... </ acitivity>声明中添加了android:theme =“ @ style / FullHeightDialog”。它只是工作。谢谢..
Indrajeet 2011年

@olivierg,但我想要一个带有完整高度对话框的按钮。有什么解决方案?
Pacerier

1
注意行requestWindowFeature必须 setContentView行之前
Fattie

虽然这样可以最好地回答实际评论,但我认为,已接受答案中的解决方案是最好的。我从一开始就这样做Dialog,但很干净,但是创建AlertDialog一个要容易得多。如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>。该AlertDialog还处理生命周期的东西,可以很方便的方式确定/取消。
Krøllebølle

67

在您的代码中添加此行

requestWindowFeature(Window.FEATURE_NO_TITLE);  

或在XML中使用主题

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

XML将是更好的实现,因为使用代码版本创建并删除标题栏会浪费资源

好的,可以尝试,但是不起作用。我得到:android.view.WindowManager $ BadTokenException:无法添加窗口-如果要显示对话框,令牌null不适用于应用程序。

将警报对话框类型更改为系统对话框(例如TYPE_SYSTEM_OVERLAY),看看是否可以解决您的问题


2
不要在requestFeature()之前调用setContentView()。
jlopez 2015年

61

像这样使用:

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

这将从对话框窗口中删除任何标题栏。


3
不要在requestFeature()之前调用setContentView()。
jlopez 2015年

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

其中dialog是我的对话框的名称。


不要在requestFeature()之前调用setContentView()
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)在AndroidManifest.xml中使用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构造函数
Justin

7

如果创建自定义Dialog类是您要走的路线,则olivierg的答案对我有用,并且是最佳解决方案。但是,令我困扰的是我无法使用AlertDialog类。我希望能够使用默认的系统AlertDialog样式。创建自定义对话框类不会具有这种样式。

因此,我找到了一个无需创建自定义类即可使用的解决方案(黑客),您可以使用现有的构建器。

AlertDialog在您的内容视图上方放置一个View作为标题的占位符。如果找到该视图并将高度设置为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;
}

当我进一步测试时,我将确保进行任何需要的其他调整。


优雅的解决方案,+ 1。你知道如何在DialogFragment中使用它吗?
Binoy Babu 2012年

@Binoy更新了DialogFragments的答案(这实际上是我个人使用的方式)
cottonBallPaws

6

我不知道这个问题是否仍然存在,但就我而言,当我从Dialog切换到DialogFragment时,

requestWindowFeature(Window.FEATURE_NO_TITLE);

不是一个选择,但我可以使用

setStyle(STYLE_NO_TITLE, 0);

而是具有相同的结果。


为了明确setStyle(STYLE_NO_TITLE, 0);起见,此行()将放入DialogFragment类的onCreate方法中。
价格


3

将整个对话框上的“重力”属性设置为“中心”。然后,您需要将该设置覆盖到对话框中您不想居中的所有子组件。


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


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小号

1

您可以AlertDialog通过定义从DialogClass 扩展的新Class 而不使用它来做到这一点:

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

这将从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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.