2012-12-26 35 views
29

私は、DatePickerDialogを作成するDialogFragmentを持っています。私はnewInstanceと呼ばれる静的メソッドを使用して、デフォルトの空のコンストラクタを使用するために初期値を設定しています。しかし、どのようにリスナーを設定する必要がありますか?画面の回転後、「完了」ボタンをクリックすると、リスナーは存在しないため何もしません。DialogFragment - 画面回転後のリスナーを保持する

public class DatePickerFragment extends DialogFragment { 
    public static final String ARG_YEAR = "year"; 
    public static final String ARG_MONTH = "month"; 
    public static final String ARG_DAY = "day"; 

    private OnDateSetListener listener_; 

    public static DatePickerFragment newInstance(OnDateSetListener listener, int year, int month, int day) { 
     final DatePickerFragment date_picker = new DatePickerFragment(); 
     date_picker.setListener(listener); 

     final Bundle arguments = new Bundle(); 
     arguments.putInt(ARG_YEAR, year); 
     arguments.putInt(ARG_MONTH, month); 
     arguments.putInt(ARG_DAY, day); 
     date_picker.setArguments(arguments); 

     return date_picker; 
    } 

    private void setListener(OnDateSetListener listener) { 
     listener_ = listener; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle saved_instance_state) { 
     final Bundle arguments = getArguments(); 
     final int year = arguments.getInt(ARG_YEAR); 
     final int month = arguments.getInt(ARG_MONTH); 
     final int day = arguments.getInt(ARG_DAY); 

     return new DatePickerDialog(getActivity(), listener_, year, month, day); 
    } 
} 

答えて

55

しかし、どのように私は、リスナーを設定することが出来るのですか?

あなたはActivityonCreate方法でリスナーの参照更新:

private OnDateSetListener mOds = new OnDateSetListener() { 

    @Override 
    public void onDateSet(DatePicker view, int year, int monthOfYear, 
      int dayOfMonth) { 
      // do important stuff 
    } 
}; 

をしてonCreate方法で:

if (savedInstanceState != null) { 
    DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager() 
      .findFragmentByTag("theTag?"); 
    if (dpf != null) { 
     dpf.setListener(mOds); 
    } 
} 
+1

優れたソリューションを文書化されています!それは完璧に働いた。ありがとう、@ Luksprog。 –

+0

正しい解決策:) –

+1

+1また、明確にするために、重要なことは、ダイアログフラグメントのタグを使用してリスナーを再適用することです。このタグは、ダイアログの 'show'メソッドの第2引数に指定されています。 ' ' DatePickerFragment DPF =(DatePickerFragment)getFragmentManager() .findFragmentByTag(「theTag; – rekaszeru

2

Luksprogの答えは正しいですが、私はちょうどしたいです解決策の鍵はfindFragmentByTag()関数です。アクティビティも画面回転後に再作成されるため、メンバーFragment変数のセッター関数を呼び出すことはできません。代わりに、この関数を使用して古いフラグメントインスタンスを見つける必要があります。

Btwの場合、DialogFragment.show()を呼び出すと、タグが2番目のパラメータになります。

+0

ありがとう、良い説明。 – CoolMind

6

私の意見では、フラグメントライフサイクルを使用してこれを行うより効率的な方法があります。あなたは、自動的にそのようにリスナーとしての活性をキャストするフラグメントのライフサイクルコールバックonAttach()onDetach()を使用することができます。

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    try { 
     _listener = (OnDateSetListener)activity; 
    } catch(ClassCastException e) { 
     // check if _listener is null before using, 
     // or throw new ClassCastException("hosting activity must implement OnDateSetListener"); 
    } 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    _listener = null; 
} 

この技法は、公式here

+0

はい、このように、異なるクラスのListenerを持つアクティビティで、同じクラスを使用することはできません(DialogFragmentと言えば)... – ARLabs

+1

どうしてですか?アクティビティで必要なリスナインタフェースを実装し、DialogFragment内の別のリスナインスタンスにキャストします。オプションをいくつか作成したい場合は、より複雑なClassCastエラー処理を行うことができます。 – d370urn3ur

+1

同じActivityが同じDialogFragmentを2回使用する必要がある場合(あなたが示唆したように)、Activityはリスナーから継承します。リスナーメソッドが呼び出されたときに、どちらが当てはまるのか分かりません。 2つの異なるリスナーインスタンスを使用する方がよいと考えてください(アクティビティではない可能性があります)。私が言ったことは、良い設計のために循環依存を避け、DialogFragmentが独自のリスナータイプを定義し、アクティビティの特殊化を知らないというhypotesisに頼っていました。 – ARLabs

関連する問題