ต้องเรียก requestFeature () ก่อนที่จะเพิ่มเนื้อหา


138

ฉันกำลังพยายามติดตั้งแถบหัวเรื่องที่กำหนดเอง:

นี่คือคลาส Helper ของฉัน:

import android.app.Activity;
import android.view.Window;

public class UIHelper {
    public static void setupTitleBar(Activity c) {
        final boolean customTitleSupported = c.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

        c.setContentView(R.layout.main);

        if (customTitleSupported) {
            c.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);
        }
    }
}

นี่คือที่ที่ฉันเรียกว่าใน onCreate ():

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setupUI();
}

private void setupUI(){
     setContentView(R.layout.main);
     UIHelper.setupTitleBar(this);
}

แต่ฉันได้รับข้อผิดพลาด:

requestFeature() must be called before adding content

คำตอบ:


336

เพียงแค่ทำในสิ่งที่ข้อความแสดงข้อผิดพลาดบอกคุณ

อย่าโทรsetContentView()มาก่อนrequestFeature().

บันทึก:

ตามที่กล่าวไว้ในความคิดเห็นสำหรับทั้งสองActionBarSherlockและAppCompatห้องสมุดจำเป็นต้องโทรrequestFeature()มาก่อนsuper.onCreate()


60
นี่คือคำตอบที่ดีงาม
บุคคลที่

60
สำหรับ ActionBarSherlock ก็จำเป็นต้องโทรrequestFeature()มาก่อนsuper.onCreate()เช่นกัน อ้างอิง: github.com/JakeWharton/ActionBarSherlock/issues/…
ศรัณย์

1
จะเกิดอะไรขึ้นถ้าคุณต้องการแสดงเค้าโครงเดียวโดยไม่มีแถบหัวเรื่องแล้วแสดงเค้าโครงด้วยแถบหัวเรื่อง? คุณจะต้องใช้requestWindowFeature(Window.FEATURE_NO_TITLE)เพื่อซ่อนจากนั้นsetContentView()สำหรับเค้าโครงแรกของคุณจากนั้นจึงrequestWindowFeature(Window.FEATURE_CUSTOM_TITLE)จะแสดงแถบชื่อเรื่องอีกครั้ง นั่นจะเป็นหลังจากsetContentView()ครั้งที่สอง
msbg

35
เป็นกรณีเดียวกับใน AppCompat ตามที่ @Saran กล่าว คุณต้องโทรหาคุณrequestFeatureก่อนsuper.onCreate()
Jaison Brooks

7
คำตอบนี้ไม่ได้ช่วยอะไรมากนัก ... แต่ฉันรู้อะไร
Ojonugwa Jude Ochalifu

23

ฉันรู้ว่าอายุเกินหนึ่งปีแล้ว แต่การโทรrequestFeature()ไม่เคยช่วยแก้ปัญหาของฉันได้ อันที่จริงฉันไม่เรียกมันเลย

มันเป็นปัญหากับการขยายมุมมองที่ฉันคิดว่า แม้จะมีการค้นหาทั้งหมดของฉันฉันก็ไม่พบวิธีแก้ปัญหาที่เหมาะสมจนกว่าฉันจะเล่นด้วยวิธีต่างๆในการขยายมุมมอง

AlertDialog.Builder เป็นวิธีแก้ปัญหาที่ง่าย แต่ต้องใช้งานมากหากคุณใช้ไฟล์ onPrepareDialog()เพื่ออัปเดตมุมมองนั้น

อีกทางเลือกหนึ่งคือการใช้ประโยชน์จาก AsyncTask สำหรับกล่องโต้ตอบ

ทางออกสุดท้ายที่ฉันใช้อยู่ด้านล่าง:

public class CustomDialog extends AlertDialog {

   private View content;

   public CustomDialog(Context context) {
       super(context);

       LayoutInflater li = LayoutInflater.from(context);
       content = li.inflate(R.layout.custom_view, null);

       setUpAdditionalStuff(); // do more view cleanup
       setView(content);           
   }

   private void setUpAdditionalStuff() {
       // ...
   }

   // Call ((CustomDialog) dialog).prepare() in the onPrepareDialog() method  
   public void prepare() {
       setTitle(R.string.custom_title);
       setIcon( getIcon() );
       // ...
   }
}

* หมายเหตุเพิ่มเติมบางประการ:

  1. อย่าพึ่งซ่อนชื่อเรื่อง มักจะมีพื้นที่ว่างทั้งๆที่ไม่ได้ตั้งชื่อเรื่อง
  2. อย่าพยายามสร้างมุมมองของคุณเองด้วยส่วนท้ายของส่วนหัวและมุมมองตรงกลาง ส่วนหัวตามที่ระบุไว้ข้างต้นอาจไม่ถูกซ่อนทั้งหมดแม้ว่าจะร้องขอ FEATURE_NO_TITLE ก็ตาม
  3. อย่าจัดรูปแบบมุมมองเนื้อหาของคุณอย่างมากด้วยแอตทริบิวต์สีหรือขนาดข้อความ ปล่อยให้กล่องโต้ตอบจัดการกับสิ่งนั้นอีกอย่างที่ชาญฉลาดคุณอาจเสี่ยงต่อการใส่ข้อความสีดำในกล่องโต้ตอบสีน้ำเงินเข้มเนื่องจากผู้ขายเปลี่ยนสี

เดิมทีฉันโพสต์ setTitle () และ setIcon () ในเมธอด onCreate () แต่การแก้ไขย้ายไปยังวิธีการจัดเตรียม () ซึ่งถูกเรียกในระหว่างเมธอด onPrepareDialog ()
Cookster

2
ขอบคุณสำหรับการแบ่งปัน. ผมคิดว่าบรรทัดต่อไปนี้อาจจะcontent = inflater.inflate(R.layout.custom_view, null); content = li.inflate(R.layout.custom_view, null);ดังนั้นจะต้องมีการแทนที่ด้วยinflater li
aLearner

14

ฉันกำลังขยายDialogFragmentและคำตอบข้างต้นไม่ได้ผล ฉันต้องใช้ getDialog () เพื่อลบชื่อ:

getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);

@ojonugwaochalifu มันย้อนกลับไปสักพักแล้วดังนั้นฉันจำไม่ได้ แต่ฉันแน่ใจว่าต้องทำก่อนวิธี setcontentView ()
อาร์กิวเมนต์ที่ผิดกฎหมาย

1
สำหรับใครก็ตามที่ประสบปัญหาเดียวกัน: ฉันได้เพิ่มรหัสนี้ใน onViewCreated ();
7geeky

2

ข้อผิดพลาดไม่ได้บอกคุณอย่างแน่นอนว่ามีอะไรผิดพลาดหรือไม่? คุณกำลังโทรrequestWindowFeatureและsetFeatureIntหลังจากที่คุณโทรsetContentViewหลังจากที่คุณเรียกกำลัง

ยังsetContentViewไงซะทำไมโทรมาสองครั้ง


2

สำหรับ SDK เวอร์ชัน 23 ขึ้นไป RuntimeException เดียวกันจะถูกโยนทิ้งหากคุณใช้ AppCompatActivity เพื่อขยายกิจกรรมของคุณ จะไม่เกิดขึ้นหากกิจกรรมของคุณมาจากกิจกรรมโดยตรง

นี่เป็นปัญหาที่ทราบใน Google ตามที่กล่าวไว้ในhttps://code.google.com/p/android/issues/detail?id=186440

วิธีแก้ปัญหาที่มีให้สำหรับสิ่งนี้คือการใช้เมธอด supportRequestWindowFeature () แทนการใช้ requestFeature ()

โปรดโหวตว่าสามารถแก้ปัญหาของคุณได้หรือไม่


1

เปลี่ยนรุ่นรวบรวม SDK , รุ่นเป้าหมาย SDKเพื่อรุ่นสร้างเครื่องมือที่จะ24.0.0ในbuild.gradle u หากประสบปัญหาในคำขอคุณลักษณะ


0

ในกรณีของฉันฉันได้แสดงDialogFragmentในActivity. ในส่วนโต้ตอบนี้ฉันเขียนในDialogFragment ลบขอบสีดำ :

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_FRAME, 0)
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    super.onCreateDialog(savedInstanceState)

    val dialog = Dialog(context!!, R.style.ErrorDialogTheme)
    val inflater = LayoutInflater.from(context)
    val view = inflater.inflate(R.layout.fragment_error_dialog, null, false)
    dialog.setTitle(null)
    dialog.setCancelable(true)
    dialog.setContentView(view)
    return dialog
}

ลบsetStyle(STYLE_NO_FRAME, 0)ในonCreate()หรือ onCreateDialogChande เนื่องจากการตั้งค่าไดอะล็อกมีการเปลี่ยนแปลงหลังจากสร้างไดอะล็อกแล้ว


0

ฉันมีปัญหานี้กับ Dialogs ซึ่งใช้ DialogFragment แบบขยายซึ่งทำงานได้ดีบนอุปกรณ์ที่ใช้ API 26 แต่ล้มเหลวกับ API 23 กลยุทธ์ข้างต้นใช้ไม่ได้ผล แต่ฉันแก้ไขปัญหาโดยการลบเมธอด onCreateView (ซึ่งมีการเพิ่มมากขึ้น เทมเพลต Android Studio ล่าสุด) จาก DialogFragment และสร้างกล่องโต้ตอบใน onCreateDialog

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