2014-01-24 47 views
0

我在擴展DialogFragment。我想使用客戶監聽器,因爲onDateSet導致了很多問題。 (不能夠取消選擇很好,在某些設備上被稱爲兩次,根本不工作別人。)如何使Exteneding DialogFragment的構建客戶端更友好?

但是問題是我的課是不是很友好的客戶端。正如它的立場,有人可能會實例化我的類,而不是設置所需的偵聽器。 由於它的編寫使用我的代碼的客戶端必須知道創建類,然後單獨設置偵聽器。

我能做些什麼,使正確使用這個類比較明顯的用戶? 我能想到的任何事情都包括更改Android不允許我這樣做的默認構造函數。

public class DatePickerDialogFragment extends DialogFragment implements OnDateSetListener { 
DatePickerDialog dp; 
DatePickerDialogFragmentListener listener; 
final Calendar calendar; 
public DatePickerDialogFragment(){ 
    calendar = Calendar.getInstance(); 
} 

public void setDatePickerDialogFragmentListener(DatePickerDialogFragmentListener dialogFragmentListener){ 
    listener = dialogFragmentListener; 
} 

public void setInitialDate(int year, int month, int day){ 
    calendar.set(year, month, day); 
} 

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
    int year = calendar.get(Calendar.YEAR); 
    int month = calendar.get(Calendar.MONTH); 
    int day = calendar.get(Calendar.DAY_OF_MONTH); 
    dp = new DatePickerDialog(getActivity(), this, year, month, day); 

    DialogInterface.OnClickListener okClickListener = new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      if (listener != null){ // if the listener has been set correctly. 
       try { 
        Field mDatePickerField = dp.getClass().getDeclaredField("mDatePicker"); 
        mDatePickerField.setAccessible(true); 
        DatePicker datePicker = (DatePicker) mDatePickerField.get(dialog); 
        listener.okClicked(datePicker, datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth()); 
       } catch (NoSuchFieldException e) { 

       } 
       catch (IllegalArgumentException e) { 

       } 
       catch (IllegalAccessException e) { 
       } 
      } 
     } 
    }; 
    DialogInterface.OnClickListener cancelClickListener = new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 

     } 
    }; 
    dp.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", cancelClickListener); 
    dp.setButton(DialogInterface.BUTTON_POSITIVE, "Ok", okClickListener); 
    return dp; 
} 

@Override 
public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) { 
    // Not using because it is inconsistant accross devices and O/S's 

} 
public interface DatePickerDialogFragmentListener { 
    public void okClicked(DatePicker datePicker, int year, int month, int day); 
    public void cancelClicked(); 
}} 

回答

0

這種情況的一般範式是提供您的片段上的接口,主機活動必須實現。例如:

public class DatePickerDialogFragment extends DialogFragment implements OnDateSetListener { 
    DatePickerDialog dp; 
    DatePickerDialogFragmentListener mListener; 
    final Calendar mCalendar; 

    public DatePickerDialogFragment(){ 
     calendar = Calendar.getInstance(); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     if (activity instanceof DatePickerDialogFragmentListener) { 
      mListener = (DatePickerDialogFragmentListener) activity; 
     } else { 
      throw new IllegalArgumentException("The Activity hosting this " 
        + "Fragment must implement DatePickerDialogFragmentListener"; 
     } 
    } 

    @Override 
    public void onDetach() { 
     mListener = null; 
    } 

    private void fireOnOkClicked() { 
     if (mListener != null) { 
      mListener.onOkClicked(); 
     } 
    } 

    private void fireOnCancelClicked() { 
     if (mListener != null) { 
      mListener.onCancelClicked(); 
     } 
    } 

    public void setInitialDate(int year, int month, int day){ 
     calendar.set(year, month, day); 
    } 

    public interface DatePickerDialogFragmentListener { 
     public void okClicked(DatePicker datePicker, int year, int month, int day); 
     public void cancelClicked(); 
    } 
} 

這樣,他們被迫實現接口,否則應用程序會拋出異常。它還可以防止內存泄漏;使用設定器來設置活動作爲偵聽器片段會泄漏該活動一旦裝置被旋轉,並且如果該監聽更新UI,這些更新會莫名其妙停止,因爲對一個老活性的參考發生。

+0

非常感謝。如果我需要在同一個活動中使用這兩個對話框,我該怎麼做?將它們包裝在實現DatePickerDialogFragmentListener的類中? – user2484014

+0

啊,這就是它變得複雜的地方。所以,你可以做的也是傳入一個標識符的參數,並將該標識符傳回給回調函數。 – kcoppock

+0

再次感謝。我可能不得不重新考慮這一點。我想製作一個包含啓動此對話框的按鈕的客戶化合物視圖,但它聽起來像這樣可能是不好的。 – user2484014

相關問題