requestFeature () phải được gọi trước khi thêm nội dung


135

Tôi đang cố gắng thực hiện một thanh tiêu đề tùy chỉnh:

Đây là lớp Người trợ giúp của tôi:

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

Đây là nơi tôi gọi nó trong onCreate ():

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

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

Nhưng tôi nhận được lỗi:

requestFeature() must be called before adding content

Đã trả lời tại đây: stackoverflow.com/questions/16939814/ từ
karma

Câu trả lời:


331

Vâng, chỉ cần làm những gì thông báo lỗi cho bạn.

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

Ghi chú:

Như đã nói trong các bình luận, đối với cả hai ActionBarSherlockAppCompatthư viện, cần phải gọi requestFeature()trướcsuper.onCreate()


60
chết tiệt, đây là một câu trả lời đẳng cấp
Một người vào

60
Đối với ActionBarSherlock, bạn cũng cần gọi requestFeature()trước super.onCreate(). Tham khảo: github.com/JakeWharton/ActionBarSherlock/issues/iêu
Saran

1
Điều gì sẽ xảy ra nếu bạn cần hiển thị một bố cục mà không có thanh tiêu đề và sau đó hiển thị một bố cục với thanh tiêu đề? Bạn sẽ phải sử dụng requestWindowFeature(Window.FEATURE_NO_TITLE)để ẩn nó, sau đó setContentView()cho bố cục đầu tiên của bạn, sau đó requestWindowFeature(Window.FEATURE_CUSTOM_TITLE)để hiển thị lại thanh tiêu đề. Đó sẽ là sau setContentView()lần thứ hai.
msbg

35
Trường hợp tương tự của nó trong AppCompat như @Saran nói. Bạn phải gọi cho bạn requestFeaturetrướcsuper.onCreate()
Jaison Brooks

7
Câu trả lời này không giúp được gì nhiều ... nhưng tôi biết gì
Ojonugwa Jude Ochalifu

23

Tôi biết nó đã hơn một tuổi, nhưng gọi điện requestFeature()không bao giờ giải quyết được vấn đề của tôi. Trong thực tế, tôi không gọi nó là tất cả.

Đó là một vấn đề với việc thổi phồng quan điểm mà tôi cho là. Bất chấp tất cả tìm kiếm của tôi, tôi không bao giờ tìm thấy một giải pháp phù hợp cho đến khi tôi chơi xung quanh với các phương pháp khác nhau để tăng cường một cái nhìn.

AlertDialog.Builder là giải pháp dễ dàng nhưng đòi hỏi nhiều công sức nếu bạn sử dụng onPrepareDialog()để cập nhật quan điểm đó.

Một cách khác là tận dụng AsyncTask cho các hộp thoại.

Một giải pháp cuối cùng mà tôi đã sử dụng là dưới đây:

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

* Một số ghi chú bổ sung:

  1. Đừng dựa vào việc che giấu tiêu đề. Thường có một khoảng trống mặc dù tiêu đề không được đặt.
  2. Đừng cố gắng xây dựng Chế độ xem của riêng bạn với chân trang tiêu đề và chế độ xem giữa. Tiêu đề, như đã nêu ở trên, có thể không bị ẩn hoàn toàn mặc dù yêu cầu FEATURE_NO_TITLE.
  3. Đừng tạo kiểu nặng cho chế độ xem nội dung của bạn bằng các thuộc tính màu hoặc kích thước văn bản. Hãy để hộp thoại xử lý điều đó, khôn ngoan khác bạn có nguy cơ đưa văn bản màu đen vào hộp thoại màu xanh đậm vì nhà cung cấp đảo ngược màu sắc.

Ban đầu tôi đã đăng setTitle () và setIcon () trong phương thức onCreate (), nhưng chỉnh sửa đã chuyển nó sang phương thức chuẩn bị () được gọi trong phương thức onPrepareDialog ().
Cookster

2
Cám ơn vì đã chia sẻ. Tôi nghĩ rằng dòng sau đây content = inflater.inflate(R.layout.custom_view, null);có lẽ nên được content = li.inflate(R.layout.custom_view, null);. Vì vậy, inflaterphải được thay thế bởi li.
aLearner

14

Tôi đã mở rộng DialogFragment và câu trả lời trên không hoạt động. Tôi đã phải sử dụng getDialog () để xóa tiêu đề:

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

@ojonugwaochalifu đó là một thời gian trước đây vì vậy tôi không nhớ chính xác nhưng tôi chắc chắn rằng nó cần phải được thực hiện trước khi phương thức setcontentView ()
Đối số bất hợp pháp

1
cho bất kỳ ai gặp phải cùng một vấn đề: Tôi đã thêm mã này vào onViewCreated ();
7geeky

2

Không phải lỗi chính xác cho bạn biết những gì sai? Bạn đang gọi requestWindowFeaturesetFeatureIntsau khi bạn gọi setContentView.

Nhân tiện, tại sao bạn gọi setContentViewhai lần?


2

Đối với SDK phiên bản 23 trở lên, cùng một RuntimeException sẽ bị ném nếu bạn đang sử dụng AppCompatActivity để mở rộng hoạt động của mình. Nó sẽ không xảy ra nếu hoạt động của bạn xuất phát trực tiếp từ Hoạt động.

Đây là sự cố đã biết trên google như được đề cập trong https://code.google.com.vn/p/android/issues/detail?id=186440

Công việc được cung cấp cho việc này là sử dụng phương thức supportRequestWindowFeature () thay vì sử dụng requestFeature ().

Vui lòng upvote nếu nó giải quyết vấn đề của bạn.


1

Thay đổi phiên bản Compile SDK , phiên bản Target SDK để Công cụ xây dựng phiên bản để 24.0.0 trong build.gradle nếu u phải đối mặt với vấn đề trong tính năng theo yêu cầu


0

Trong trường hợp của tôi tôi đã giới thiệu DialogFragmenttrong Activity. Trong đoạn thoại này, tôi đã viết như trong DialogFragment, loại bỏ viền đen :

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
}

Hoặc loại bỏ setStyle(STYLE_NO_FRAME, 0)trong onCreate()hoặc chande / loại bỏ onCreateDialog. Bởi vì cài đặt hộp thoại đã thay đổi sau khi hộp thoại được tạo.


0

Tôi đã gặp sự cố này với Hộp thoại dựa trên Hộp thoại mở rộng hoạt động tốt trên các thiết bị chạy API 26 nhưng không thành công với API 23. Các chiến lược trên không hoạt động nhưng tôi đã giải quyết vấn đề bằng cách xóa phương thức onCreateView (đã được thêm vào bằng cách thêm mẫu Android Studio gần đây) từ DialogFragment và tạo hộp thoại trong onCreateDialog.

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.