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 ที่ฉันพยายามเรียกดูไม่มีอยู่
หากฉันยกเลิกการคอมเม้นต์ส่วนที่ฉันใช้ Dialog Constructor ทุกอย่างทำงานได้ดี แต่สำหรับชื่อเรื่องเหนือเค้าโครงข้อความโต้ตอบของฉัน


7
@Janusz เลือกคำตอบของคุณอีกครั้งเพื่อstackoverflow.com/a/3407871/632951
Pacerier

ลองใช้stackoverflow.com/questions/6263639/…แทนคำตอบก่อนหน้านี้ ... คำตอบง่ายๆ
Mohammed mansoor

เพียงแค่อย่าโทร AlertDialog.Builder.setTitle () และกล่องโต้ตอบของคุณจะปรากฏขึ้นโดยไม่มีชื่อ
marvatron

คำตอบ:


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
ฉันคิดว่าคุณอาจอ่านคำถามผิด? Janusz ได้แสดงกล่องโต้ตอบแบบกำหนดเองแล้วและต้องการข้อมูลเกี่ยวกับการลบชื่อ
Donal Rafferty

17
ตามเอกสารอย่างเป็นทางการ "กล่องโต้ตอบที่ทำกับคลาสไดอะล็อกฐานต้องมีหัวเรื่องหากคุณไม่เรียก setTitle () พื้นที่ที่ใช้สำหรับชื่อนั้นจะว่างเปล่า แต่ยังคงมองเห็นได้ถ้าคุณไม่ ' ไม่ต้องการชื่อเลยคุณควรสร้างกล่องโต้ตอบที่กำหนดเองโดยใช้คลาส AlertDialog " ฉันไม่ได้ทดลองกับมันเป็นการส่วนตัว แต่นั่นจะแนะนำว่าแม้จะใช้รูปแบบไดอะล็อกที่กำหนดเองหรือธีมมันเป็นไปไม่ได้ที่จะลบพื้นที่ชื่อ
Steve Haley

2
ความคิดที่สอง: ฉันคิดว่าเราเข้าใจ "ชื่อ" แตกต่างกัน ฉันคิดว่าเขากำลังพูดถึงพื้นที่ด้านบนของหน้าต่างป๊อปอัปไม่ใช่ชื่อที่ด้านบนของแอพ
Steve Haley

11
@SteveHaley ไม่สามารถซ่อนได้โดยใช้บรรทัดต่อไปนี้dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Sami Eltamawy

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 (หรือใช้ตัวสร้าง) เพราะมันจะปิดการใช้งานชื่อและใช้แบบกำหนดเองภายใน

ฉันดูที่แหล่ง 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 แนะนำ จากนั้นฉันเพิ่ม android: theme = "@ style / FullHeightDialog" ในการประกาศ <activity> ... </acitivity> ในไฟล์ Manifest มันใช้งานได้จริง ขอบคุณ ..
Indrajeet

@ olivierg แต่ฉันต้องการปุ่มที่มีกล่องโต้ตอบเต็มความสูง ทางออกคืออะไร
Pacerier

1
หมายเหตุบรรทัด requestWindowFeature ต้องก่อนที่จะสาย 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: ไม่สามารถเพิ่มหน้าต่าง - โทเค็น null ไม่ได้สำหรับแอปพลิเคชันหากฉันต้องการแสดงข้อความโต้ตอบ

เปลี่ยนประเภทไดอะล็อกการแจ้งเตือนเป็นไดอะล็อกระบบ (เช่น TYPE_SYSTEM_OVERLAY) และดูว่าจะช่วยแก้ไขปัญหาของคุณได้หรือไม่


2
อย่าเรียก setContentView () ก่อนที่จะทำการร้องขอคุณสมบัติ ()
jlopez

61

ใช้แบบนี้:

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

นี่จะเป็นการลบแถบหัวเรื่องออกจากหน้าต่างข้อความ


3
อย่าเรียก setContentView () ก่อนที่จะทำการร้องขอคุณสมบัติ ()
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);

โดยที่ dialog เป็นชื่อของไดอะล็อกของฉัน


อย่าเรียก setContentView () ก่อน requestFeature ()
jlopez

29

ในรหัสของคุณถ้าคุณใช้requestWindowFeature(Window.FEATURE_NO_TITLE); ให้แน่ใจว่ามันไปก่อนdialog.setContentView();มิฉะนั้นจะทำให้โปรแกรมประยุกต์ที่ผิดพลาด


ค่อนข้างสงสัยที่จะลองก่อนและค่อนข้างแปลกใจว่ามันใช้งานได้ชัดเจน ตั้งแต่ใน android.developer.com พวกเขากล่าวอย่างชัดเจนว่ามันเป็นสิ่งจำเป็นสำหรับการโต้ตอบที่กำหนดเองที่จะมีชื่อ : P
richardlin

10

ฉันพบ Three Way เพื่อทำสิ่งนี้>

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)
Jon Willis

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

นี่เป็นสิ่งเดียวที่ทำงานได้สำหรับฉัน ... ด้วยเหตุผลบางอย่างข้อเสนอแนะอื่น ๆ ทั้งหมดไม่ทำงาน สิ่งเดียวที่ฉันอยากจะแนะนำคือการทำให้ตัวสร้างสาธารณะและยังให้ตัวสร้างกล่องโต้ตอบอื่น ๆ ที่ใช้บริบทเท่านั้น
Justin

7

คำตอบของ oliviergเหมาะกับฉันและเป็นทางออกที่ดีที่สุดหากสร้างคลาสไดอะล็อกที่กำหนดเองเป็นเส้นทางที่คุณต้องการไป อย่างไรก็ตามมันรบกวนฉันว่าฉันไม่สามารถใช้คลาส 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 จากนั้นสร้างและส่งคืนกล่องโต้ตอบของคุณเหมือนตัวอย่างแรกข้างต้น การเปลี่ยนแปลงเพียงอย่างเดียวคือคุณควรส่งเท็จเป็นพารามิเตอร์ที่ 3 (แสดง) เพื่อที่จะไม่เรียกใช้ 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

@Binoy อัปเดตคำตอบสำหรับ DialogFragments (นั่นคือวิธีที่ฉันใช้เป็นการส่วนตัว)
cottonBallPaws

6

ฉันไม่ทราบว่าคำถามนี้ยังคงเกิดขึ้นจริง แต่ในกรณีของฉันเมื่อฉันเปลี่ยนจากกล่องโต้ตอบเป็น DialogFragment

requestWindowFeature(Window.FEATURE_NO_TITLE);

ไม่ใช่ตัวเลือก แต่ฉันสามารถใช้ได้

setStyle(STYLE_NO_TITLE, 0);

แทนด้วยผลลัพธ์เดียวกัน


เพื่อชี้แจงบรรทัดนี้ ( setStyle(STYLE_NO_TITLE, 0);) จะไปในวิธี onCreate ของคลาส DialogFragment ของคุณ
ราคา

4

ตั้งชื่อเป็นสตริงที่ว่างเปล่าโดยใช้ตัวสร้าง

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

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โดยการกำหนด Class ใหม่ที่ขยายจากDialogClass ดังนี้:

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.