Android: Làm cách nào để tạo Hộp thoại mà không có tiêu đề?


269

Tôi đang cố gắng tạo một hộp thoại tùy chỉnh trong Android. Tôi tạo Hộp thoại của mình như thế này:

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

Mọi thứ đều hoạt động tốt, ngoại trừ tiêu đề của Hộp thoại. Ngay cả khi tôi không đặt tiêu đề của hộp thoại, cửa sổ bật lên hộp thoại có một khoảng trống ở vị trí của hộp thoại.

Có cách nào để ẩn phần này của Hộp thoại không?

Tôi đã thử nó với AlertDialog nhưng có vẻ như bố cục không được đặt đúng:

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

Nếu tôi sử dụng mã này, tôi sẽ nhận được Ngoại lệ con trỏ null ở dòng cuối cùng. Hộp thoại không phải là null nên TextView tôi cố truy xuất không tồn tại.
Nếu tôi bỏ qua phần tôi sử dụng Trình tạo hộp thoại, mọi thứ sẽ hoạt động tốt nhưng đối với tiêu đề phía trên bố cục hộp thoại của tôi.


7
@Janusz kiểm tra lại câu trả lời của bạn cho stackoverflow.com/a/3407871/632951
Pacerier

hãy thử stackoverflow.com/questions/6263639/ Thay vì câu trả lời trước đó ... câu trả lời đơn giản
Mohammed mansoor

Chỉ cần không gọi AlertDialog.Builder.setTitle () và hộp thoại của bạn sẽ xuất hiện mà không có tiêu đề.
marvatron

Câu trả lời:


208

Bạn có thể ẩn tiêu đề của hộp thoại bằng cách sử dụng:

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


Phiên bản trước của câu trả lời này, quá phức tạp:

Bạn cần sử dụng một AlertDialog. Có một lời giải thích tốt trên trang web của Nhà phát triển Android về các hộp thoại tùy chỉnh .

Tóm lại, bạn làm điều này với mã như được sao chép dưới đây từ trang web chính thức. Điều đó có một tệp layot ​​tùy chỉnh, thổi phồng nó, cung cấp cho nó một số văn bản và biểu tượng cơ bản, sau đó tạo nó. Bạn sẽ cho thấy nó sau đó với 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();

Đáp lại bình luận:

Tôi giả sử rằng TextView với id nrnằm trong Chế độ xem mà bạn đang thực hiện View view = inflater..... Nếu vậy, thì bạn cần thay đổi chỉ một bit: thay vì dialog.findView...thực hiện view.findView.... Sau đó, khi bạn đã thực hiện điều đó, hãy nhớ sử dụng hộp thoại.show () hoặc thậm chí builder.show () mà không bận tâm đến builder.create ().


4
Tôi nghĩ rằng bạn có thể đã đọc sai câu hỏi? Janusz đã có hộp thoại tùy chỉnh hiển thị và chỉ yêu cầu thông tin về việc xóa tiêu đề
Donal Rafferty

17
Theo tài liệu chính thức, "Hộp thoại được tạo bằng lớp Hộp thoại cơ sở phải có tiêu đề. Nếu bạn không gọi setTitle (), thì không gian được sử dụng cho tiêu đề vẫn trống, nhưng vẫn hiển thị. Nếu bạn không ' Nếu muốn có một tiêu đề, thì bạn nên tạo hộp thoại tùy chỉnh bằng lớp AlertDialog. " Cá nhân tôi đã thử nghiệm với nó, nhưng điều đó sẽ gợi ý rằng ngay cả khi sử dụng bố cục hoặc chủ đề hộp thoại tùy chỉnh, không thể xóa không gian tiêu đề.
Steve Haley

2
Suy nghĩ thứ 2: Tôi nghĩ chúng ta hiểu "tiêu đề" khác nhau. Tôi cho rằng anh ta đang nói về không gian ở đầu cửa sổ bật lên, không phải tiêu đề ở đầu ứng dụng.
Steve Haley

11
@SteveHaley, Không thể ẩn nó bằng dòng saudialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Sami Eltamawy

1
Hãy chắc chắn rằng bạn thực hiện hộp thoại.requestWindowFeature (Window.FEATURE_NO_TITLE); TRƯỚC KHI bạn tăng cường xem hộp thoại của bạn.
Alexey Podlasov

585

FEATURE_NO_TITLE hoạt động khi tạo hộp thoại từ đầu, như trong:

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

Nhưng nó không hoạt động khi tạo AlertDialog (hoặc sử dụng Trình tạo), vì nó đã vô hiệu hóa tiêu đề và sử dụng một tùy chỉnh bên trong.

Tôi đã xem xét các nguồn SDK và tôi nghĩ rằng nó không thể hoạt động được. Vì vậy, để loại bỏ khoảng cách trên cùng, giải pháp duy nhất là tạo một hộp thoại tùy chỉnh từ đầu IMO, bằng cách sử dụng trực tiếp lớp Hộp thoại.

Ngoài ra, người ta có thể làm điều đó với một kiểu, ví dụ như trong tệp kiểu tệp:

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

Và sau đó:

Dialog dialog = new Dialog(context, R.style.FullHeightDialog);

Thay vì tạo một hộp thoại tùy chỉnh từ đầu, tôi đã tạo tệp style.xml theo đề xuất của oliverg. Và sau đó, tôi đã thêm android: theme = "@ style / FullHeightDialog" vào khai báo <Activity> ... </ acergy> trong tệp Manifest. Nó chỉ hoạt động. Cảm ơn ..
Indrajeet

@olivierg nhưng tôi muốn một nút có hộp thoại chiều cao đầy đủ. giải pháp là gì?
Pacerier

1
Lưu ý dòng requestWindowFeature phải TRƯỚC dòng setContentView.
Fattie

Trong khi điều này trả lời các ý kiến ​​thực tế tốt nhất, giải pháp trong câu trả lời được chấp nhận là tốt nhất theo ý kiến ​​của tôi. Tôi bắt đầu làm nó như thế này, với sự sạch sẽ Dialog, nhưng việc tạo ra AlertDialognó dễ dàng hơn nhiều. Như đã nêu trong các tài liệu : 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>. Việc này AlertDialogcũng xử lý các công cụ vòng đời và ok / hủy trong cách cư xử dễ dàng.
Krøllebølle

67

Trong mã của bạn thêm dòng này

requestWindowFeature(Window.FEATURE_NO_TITLE);  

Hoặc trong XML sử dụng một chủ đề

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

XML sẽ là một triển khai tốt hơn vì với phiên bản mã, thanh tiêu đề được tạo và sau đó bị loại bỏ, điều này gây lãng phí tài nguyên

Ok thử tốt nhưng nó không hoạt động. Tôi nhận được: android.view.WindowManager $ BadTokenException: Không thể thêm cửa sổ - mã thông báo null không dành cho ứng dụng nếu tôi muốn chuyển hộp thoại.

Thay đổi loại hộp thoại cảnh báo thành hộp thoại hệ thống (ví dụ: TYPE_SYIUS_OVERLAY) và xem điều này có giải quyết được sự cố của bạn không


2
Đừng gọi setContentView () trước requestFeature ().
jlopez

61

Sử dụng như thế này:

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

Điều này sẽ loại bỏ bất kỳ thanh tiêu đề từ cửa sổ hộp thoại.


3
Đừng gọi setContentView () trước requestFeature ().
jlopez

2
Làm thế nào để tôi mang nó trở lại sau?
nhà phát triển Android

58

Sử dụng mã dưới đây trước setcontentview: -

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

Lưu ý : Bạn phải có mã ở trên, theo cùng thứ tự và dòng. requestWindowFeaturephải ở trước dòng setContentView.


Khi sử dụng trong Dialogfragment, giải pháp này hoạt động tốt hơn đối với tôi vì câu trả lời được chấp nhận sẽ tạo ra một khoảng cách dọc nhỏ giữa khung hộp thoại và chế độ xem nội dung bên trong.
Sebastian Roth

38

bạn có thể xóa tiêu đề bằng cách

dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

trong đó hộp thoại là tên của hộp thoại của tôi.


Đừng gọi setContentView () trước requestFeature ()
jlopez

29

Trong mã của bạn nếu bạn sử dụng requestWindowFeature(Window.FEATURE_NO_TITLE); hãy chắc chắn rằng nó đi trước dialog.setContentView();nếu không nó sẽ khiến ứng dụng bị sập.


khá nghi ngờ để thử trước và khá ngạc nhiên rằng nó rõ ràng hoạt động. vì trong android.developer.com, họ nói rõ ràng rằng hộp thoại tùy chỉnh phải có tiêu đề. : P
richardlin

10

Tôi tìm thấy Three Way để làm điều này>

1) Sử dụng requestWindowFeature

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

2) Sử dụng style (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) Sử dụng chủ đề XML trong AndroidManifest.xml

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

1
Phương thức một nên là hộp thoại.requestWindowFeature (Window.FEATURE_NO_TITLE);
Jon Willis

10

Trong lớp Custom_Dialog.java của bạn thêm 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 
    }
}

Đây là điều duy nhất làm việc cho tôi ... vì một số lý do, tất cả các đề xuất khác không hoạt động. Điều duy nhất tôi muốn giới thiệu là làm cho công cụ xây dựng công khai và cũng cung cấp công cụ xây dựng Hộp thoại khác chỉ mất một Ngữ cảnh
Justin

7

câu trả lời của olivierg làm việc cho tôi và là giải pháp tốt nhất nếu tạo một lớp Hộp thoại tùy chỉnh là con đường bạn muốn đi. Tuy nhiên, điều đó làm phiền tôi rằng tôi không thể sử dụng lớp AlertDialog. Tôi muốn có thể sử dụng kiểu AlertDialog mặc định của hệ thống. Tạo một lớp hộp thoại tùy chỉnh sẽ không có kiểu này.

Vì vậy, tôi đã tìm thấy một giải pháp (hack) sẽ hoạt động mà không phải tạo một lớp tùy chỉnh, bạn có thể sử dụng các trình xây dựng hiện có.

AlertDialog đặt Chế độ xem bên trên chế độ xem nội dung của bạn làm trình giữ chỗ cho tiêu đề. Nếu bạn tìm thấy chế độ xem và đặt chiều cao thành 0, không gian sẽ biến mất.

Tôi đã thử nghiệm điều này trên 2.3 và 3.0 cho đến nay, có thể nó chưa hoạt động trên mọi phiên bản.

Đây là hai phương thức trợ giúp để làm điều đó:

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

Đây là một ví dụ về cách nó được sử dụng:

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

    showDialogWithNoTopSpace(yourCustomView, dialog, true);

Nếu bạn đang sử dụng tính năng này với DialogFragment, hãy ghi đè onCreateDialogphương thức DialogFragment . Sau đó tạo và trả lại hộp thoại của bạn như ví dụ đầu tiên ở trên. Thay đổi duy nhất là bạn nên chuyển sai thành tham số thứ 3 (hiển thị) để nó không gọi show () trên hộp thoại. DialogFragment sẽ xử lý việc đó sau.

Thí dụ:

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

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

Khi tôi kiểm tra điều này hơn nữa, tôi chắc chắn sẽ cập nhật với bất kỳ tinh chỉnh bổ sung nào cần thiết.


Giải pháp thanh lịch, +1. Bạn có biết làm thế nào để sử dụng điều này trong DialogFragment?
Binoy Babu

@Binoy đã cập nhật câu trả lời cho DialogFragments (đó thực sự là cách cá nhân tôi sử dụng nó)
cottonBallPaws

6

Tôi không biết câu hỏi này có còn thực tế không, nhưng trong trường hợp của tôi, khi tôi chuyển từ Hộp thoại sang Hộp thoại,

requestWindowFeature(Window.FEATURE_NO_TITLE);

không phải là một lựa chọn, nhưng tôi có thể sử dụng

setStyle(STYLE_NO_TITLE, 0);

thay vào đó với kết quả tương tự.


Để làm rõ, dòng này ( setStyle(STYLE_NO_TITLE, 0);) sẽ đi theo phương thức onCreate của lớp DialogFragment của bạn.
Giá

4

Đặt tiêu đề thành chuỗi trống bằng cách sử dụng trình xây dựng.

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

3

đặt thuộc tính "trọng lực" trên toàn bộ hộp thoại thành "chính giữa". Sau đó, bạn sẽ cần ghi đè cài đặt đó cho tất cả các thành phần con trong hộp thoại mà bạn không muốn đặt ở giữa.


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

trong XML sử dụng một chủ đề

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

3

Nếu chúng ta chỉ đơn giản sử dụng hộp thoại mà không có setTitle(), thì điều đó có hiệu quả trong việc loại bỏ không gian của tiêu đề không?

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

3

Hãy nghĩ rằng bạn có thể sử dụng ngay bây giờ:

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

2
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", 
                             "Loading. Please wait...", true);

tạo một hộp thoại ít tiêu đề


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

Trong khi sử dụng AlertDialog, việc không sử dụng sẽ setTitle()khiến tiêu đề biến mất


1

Sau một loạt các vụ hack, tôi đã làm việc này:

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

chuyện gì đã xảy dialogra ở đây vàgetResources()
Kartheek s

1

Bạn có thể làm điều này mà không cần sử dụng bằng AlertDialogcách định nghĩa Lớp mới mở rộng từ DialogLớp như thế này:

public class myDialog extends Dialog {
    public myDialog(Context context) {
        super(context);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    }
}

1

Đây là điều bạn có thể làm AlertBuilderđể làm cho tiêu đề biến mất:

TextView title = new TextView(this);
title.setVisibility(View.GONE);
builder.setCustomTitle(title);

1

Dùng cái này

    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

hộp thoại_custom .requestWindowFeature (Window.FEATURE_NO_TITLE);

điều này sẽ loại bỏ tiêu đề từ hộp thoại cutom.

Lưu ý thêm các dòng này trước khi thêm nội dung .. ví dụ:

     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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.