2011-01-11 29 views
13

tôi là tạo ra một hộp thoại tùy chỉnh chứa một EditText để tôi có thể nhận được dữ liệu văn bản từ người dùng:vấn đề Dialog: requestFeature() phải được gọi trước khi thêm nội dung

final EditText newKey = (EditText) findViewById(R.id.dialog_result); 
AlertDialog.Builder keyBuilder = new AlertDialog.Builder(StegDroid.this); 
keyBuilder 
.setCancelable(false) 
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
     Log.v("Dialog","New Key: "+newKey.getText().toString()); 
    } 
}) 
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
AlertDialog dialog = keyBuilder.create(); 
dialog.setTitle("Decryption Failed"); 
dialog.setContentView(R.layout.decrypt_failed_dialog); 
dialog.show(); 

Tuy nhiên tôi luôn có được ngoại lệ này:

01-11 18:49:00.507: ERROR/AndroidRuntime(3461): android.util.AndroidRuntimeException: requestFeature() must be called before adding content 
01-11 18:49:00.507: ERROR/AndroidRuntime(3461):  at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:181) 
01-11 18:49:00.507: ERROR/AndroidRuntime(3461):  at com.android.internal.app.AlertController.installContent(AlertController.java:199) 
01-11 18:49:00.507: ERROR/AndroidRuntime(3461):  at android.app.AlertDialog.onCreate(AlertDialog.java:251) 

... 

tại dòng dialog.show(). Tôi nên làm gì để loại bỏ điều này?

Trả lời

34

Bạn cần đặt chế độ xem tùy chỉnh trước khi tạo hộp thoại. Ngoài ra, bạn cần sử dụng setView(View) thay vì setContentView() nếu bạn đang sử dụng các nút dương và âm mặc định được cung cấp cho bạn theo số AlertDialog.

final EditText newKey = (EditText) findViewById(R.id.dialog_result); 
AlertDialog.Builder keyBuilder = new AlertDialog.Builder(StegDroid.this); 
keyBuilder 
.setCancelable(false) 
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
     Log.v("Dialog","New Key: "+newKey.getText().toString()); 
    } 
}) 
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
keyBuilder.setTitle("Decryption Failed"); 
keyBuilder.setView(getLayoutInflater().inflate(R.layout.decrypt_failed_dialog, null)); 
AlertDialog dialog = keyBuilder.create(); 
dialog.show(); 
+2

Sẽ thật thú vị khi thêm nhận xét để người khác có thể dễ dàng tìm ra điều đã được thực hiện khác mà không phải so sánh mã. – codinguser

+0

Bạn là đúng dude ... Tôi không có thời gian ngay bây giờ. Bạn có nhớ chỉnh sửa câu trả lời để làm cho câu trả lời chính xác hơn không? – Cristian

+3

Cảm ơn! Bạn đã lưu ngày của tôi với "... bạn cần phải sử dụng setView (View) thay vì setContentView() ..." :) –

4

Cũng đảm bảo bạn không trả lại hộp thoại đã được hiển thị. Ví dụ: ProgressDialog có phương pháp tĩnh tiện dụng show() có một số tham số và trả về một ProgressDialog. Hóa ra bạn không thể sử dụng phương thức đó và trả về kết quả ProgressDialog, bởi vì sau đó khi hệ điều hành cố gắng hiển thị nó (và nó đã được hiển thị), nó sẽ ném cùng ngoại lệ này.

Hãy coi chừng, quá: hành vi trên có kinh nghiệm trên trình giả lập Android, nhưng thực tế nó không ném ngoại lệ và chỉ hoạt động tốt trên Droid Incredible chạy 2.2 của tôi.

2

Tôi gặp sự cố tương tự. Nhưng hộp thoại của tôi đã được hiển thị cho IME. Khi tôi chuyển sang Dialog thay vì AlertDialog, và bỏ qua tạo, chương trình làm việc cho tôi.

-3

Cách chính xác để giải quyết vấn đề này:

requestFeature(int) là một phương pháp Window. Bạn phải nhập lớp này (android.view.Window).

Và bạn phải lấy Cửa sổ của đối tượng AlertDialog.Builder. Sau đó, gọi requestFeature(int). Tham số đầu vào là một hằng số của Window.

keyBuilder.getWindow().requestFeature(Window.FEATURE_ACTION_BAR);

4

Tôi đã chạy vào này khoảng một năm trước và cố định nó một cách sử dụng mã lạ. Một lần nữa, một ứng dụng tôi đang làm việc trên có một đoạn mà sẽ hiển thị bình thường trên điện thoại, nhưng trong một cuộc đối thoại trên máy tính bảng. Tôi đã giải quyết nó như sau:

public class MyDialogFragment extends DialogFragment { 
    private View mLayout; 
    private ViewGroup mContainer; 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     mContainer = container; 
     if (getShowsDialog()) { 
      // one could return null here, or be nice and call super() 
      return super.onCreateView(inflater, container, savedInstanceState); 
     } 
     return getLayout(inflater, container); 
    } 

    private View getLayout(LayoutInflater inflater, ViewGroup container) { 
     mLayout = inflater.inflate(R.layout.my_layout, container, false); 
     return mLayout; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     return new AlertDialog.Builder(getContext()) 
       .setPositiveButton(R.string.ok, null) 
       .setNegativeButton(R.string.cancel, null) 
       .setNeutralButton(R.string.filter_clear_selection, null) 
       .setView(getLayout(LayoutInflater.from(getContext()), mContainer)) 
       .create() 
      ; 
    } 
} 

Điều này cho phép tôi thêm đoạn của mình như bất kỳ đoạn bình thường nào (trong bố cục), nhưng cũng hiển thị hộp thoại ở nơi chạy tự động.

3

Dành cho những người gặp sự cố này khi sử dụng DialogFragment.

Trong trường hợp của tôi, điều này đã xảy ra vì tôi đã mở rộng lớp DialogFragment không chính xác. Tôi đã quay lại chế độ xem trên onCreateView() VÀ CSONG trả lại hộp thoại tùy chỉnh trên onCreateDialog().Các tài liệu khẳng định:

Bạn có thể có một thiết kế giao diện người dùng mà bạn muốn có một mảnh của giao diện người dùng để xuất hiện như một hộp thoại trong một số tình huống, nhưng như một màn hình đầy đủ hoặc nhúng đoạn trong những người khác (có lẽ tùy thuộc vào cho dù thiết bị là màn hình lớn hoặc màn hình nhỏ). Lớp DialogFragment cung cấp cho bạn sự linh hoạt này vì nó vẫn có thể hoạt động như một đoạn mã có thể nhúng được .

Tuy nhiên, bạn không thể sử dụng AlertDialog.Builder hoặc các đối tượng hộp thoại khác để tạo hộp thoại trong trường hợp này. Nếu bạn muốn DialogFragment là có thể nhúng, bạn phải xác định giao diện người dùng của hộp thoại trong bố cục, sau đó tải bố cục trong gọi lại onCreateView().

Giải quyết sự cố bằng cách không tạo bất kỳ thứ gì trên onCreateDialog() (chỉ trả về triển khai siêu lớp).

Các vấn đề liên quan