33

Tôi có một lớp v4 hỗ trợ FragmentActivity thực hiện hai phần cạnh nhau (loại như gmail) và một nút có thể hiển thị DialogFragment.Android DialogFragment biến mất sau khi thay đổi định hướng

Tất cả đều hoạt động tốt trừ khi tôi có thay đổi định hướng. Khi tôi có một sự thay đổi định hướng, các trạng thái của các mảnh vỡ sẽ không được lưu lại.

Và vấn đề chính là nếu tôi có một FragmentDialog mở, nó chỉ đơn giản biến mất.

Tôi đã đặt setRetainInstance(true); trong tất cả các đoạn nhưng không hiệu quả.

Trong tệp kê khai của tôi, tôi đã bao gồm android:configChanges="orientation" nhưng vẫn không giúp được gì.

Đây là các mẫu mã của tôi, cảm ơn sự giúp đỡ của bạn.

public class AddMasterDialog extends DialogFragment { 

    private int mTitle; 
    private int mPrompt; 
    private OnClickListener onSaveListener; 
    private OnClickListener onCancelListener; 

    public AddMasterDialog newInstance(int title, int prompt) { 
     AddMasterDialog simpleDialog = new AddMasterDialog(title, prompt); 
     return simpleDialog; 
    } 

    public AddMasterDialog() { 
     // Empty constructor required for DialogFragment 
    } 
    public AddMasterDialog(int title, int prompt) { 
     // Empty constructor required for DialogFragment 
     mTitle = title; 
     mPrompt = prompt; 
    } 
    public void setSaveButton(OnClickListener save){ 
     onSaveListener = save; 
    } 
    public void setCancelButton(OnClickListener cancel){ 
     onCancelListener = cancel; 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 

     //if(savedInstanceState == null){ 
      View view = inflater.inflate(R.layout.add_new_simple, container); 
      getDialog().setTitle(mTitle); 
      ((TextView) view.findViewById(R.id.add_simple_new_value_prompt)).setText(mPrompt); 

      Button saveButton = (Button) view.findViewById(R.id.add_simple_save_button); 
      saveButton.setOnClickListener(onSaveListener); 

      //Cancel Button 
      Button cancelButton = (Button) view.findViewById(R.id.add_simple_cancel_button); 
      cancelButton.setOnClickListener(onCancelListener); 
      return view; 
     //} 
    } 
} 

và các hoạt động chính của tôi:

private void initiateAddMasterPopupWindow() { 
     try { 
      addMasterDialog = new AddMasterDialog(R.string.add_new_master_dialog_title, R.string.add_master_new_value_prompt); 
      addMasterDialog.setSaveButton(saveNewMasterClickListener); 
      addMasterDialog.setCancelButton(cancelNewMasterClickListener); 
      FragmentManager fm = getSupportFragmentManager(); 
      addMasterDialog.show(fm, ADD_NEW_MASTER); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

Trả lời

70

Được rồi, vì vậy vấn đề này có vẻ là với thư viện DialogFragment tương thích.

Sự cố đã được mô tả trong this bài đăng.

"Một loại bỏ thông báo lỗi thời cho đoạn được giữ lại trong hàng đợi thông điệp. Nó được xếp hàng bởi DialogFragment.onDestroyView() khi gạt bỏ hộp thoại cũ và được kích hoạt lại sau khi tạo hộp thoại mới.

Một cách giải quyết nhanh chóng (và có thể bẩn) là để ghi đè onDestroyView() và xóa bỏ người nghe trước khi gọi super.onDestroyView() "

Thêm mã sau đây để DialogFragment tôi đã giải quyết vấn đề này:

@Override 
public void onDestroyView() { 
    if (getDialog() != null && getRetainInstance()) { 
     getDialog().setDismissMessage(null); 
    } 
    super.onDestroyView(); 
} 
+3

mát sửa chữa, hoạt động độc đáo. –

13

Vì lợi ích của linh hồn tội nghiệp (Me) có cùng vấn đề vì nhiều lý do khác nhau, tôi sẽ đăng bài này. Đoạn thoại cần được bảo tồn tự động miễn là bạn làm như sau:

  1. Nếu bạn gọi một Activity onSaveInstanceState(), chắc chắn rằng bạn gọi hàm siêu !!!!. Trong trường hợp của tôi, đó là chìa khóa. Ngoài ra hãy chắc chắn bạn làm điều tương tự trong Fragment.
  2. Nếu bạn sử dụng setRetainInstance, bạn sẽ cần phải lưu trữ các giá trị theo cách thủ công và áp dụng lại chúng. Nếu không, bạn sẽ không thể lo lắng về nó, trong hầu hết các trường hợp. Nếu bạn đang làm một cái gì đó phức tạp hơn một chút, bạn có thể cần phải setRetainInstance(true), nhưng nếu không thì hãy bỏ qua nó. Trong trường hợp của tôi, tôi cần phải sử dụng nó để lưu trữ một hạt giống ngẫu nhiên cho một trong các lớp học của tôi, nhưng nếu không tôi đã ổn.
  3. Một số người đã phàn nàn về một lỗi trong thư viện hỗ trợ, trong đó một tin nhắn loại bỏ được gửi khi nó không được. Thư viện hỗ trợ mới nhất dường như đã sửa lỗi đó, vì vậy bạn không cần phải lo lắng về điều đó.

Bạn không cần phải làm bất cứ điều gì ưa thích như lưu trữ thủ công ra khỏi đoạn, nó sẽ được thực hiện tự động nếu bạn làm theo các bước sau. Nhìn chung, điều này dường như làm cho lừa cho bất cứ ai có một thư viện hỗ trợ hiện đại hơn.

+4

Cảm ơn bước 1 – IHeartAndroid

1

Ngoài việc đặt setRetainInstance(true);, chỉ cần đặt mã sau vào DialogFragment của bạn. Nó là một giải pháp thử nghiệm.

private boolean isDismissible = false; 

@Override 
public void dismiss() { 

    try { 

     isDismissible = true; 
     super.dismiss(); 

     Log.d(getClass().getSimpleName(), "Dialog dismissed!"); 

    } catch (IllegalStateException ilse) { 
    } 
} 

@Override 
public void onDismiss(DialogInterface dialog) { 

    // So that dialog should not dismiss on orientation change 
    if (isDismissible) { 

     // So that dialog can be dismissed 
     super.onDismiss(dialog); 
    } 
} 
+0

Nó tạo nhiều hộp thoại khi thay đổi hướng. –

2

Trong trường hợp của tôi, tôi đã có một DialogFragment thấy khác DialogFragment sử dụng

listDialogFragment.show(getChildFragmentManager(), "TAG"); 

Thay đổi nó để

listDialogFragment.show(getActivity().getSupportFragmentManager(), "TAG"); 

khắc phục sự cố

+0

NB thay đổi của bạn chính xác giống như gọi 'listDialogFragment.show (getFragmentManager()," TAG ");' – William

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