3

私は自分のアプリケーションの一部を(ちょうどアクティビティから)フラグメントに切り換えています。私は何かが完全に欠落しているか、AlertDialogを表示するプロセス全体を複雑にしています。Android:AlertDialogs and Fragments

まず、ここで私がやろうとしていることは次のとおりです。それぞれのボトムに関連付けられたコールバックメソッドを含む、肯定的なボタンと否定的なボタンを含むいくつかの警告ダイアログを表示します。ダイアログは、画面の回転を生き残る(つまり、再作成する)必要があります。

前に:以前は、適切なコールバックメソッドなどでAlertDialogを作成して表示するだけでした。これを表示すると、システムは画面の回転を含むすべての処理を行います。

Now:私のフラグメントからAlertDialogを作成して表示すると、画面の回転中や、破棄中にLogCatのリークメモリに従って再作成されません。フラグメントに関する新しい開発者ドキュメントによると、DialogFragmentを使用してAlertDialogを作成して、フラグメントマネージャが画面の回転などを処理できるようにする必要があります(ここでは、http://developer.android.com/reference/android/app/DialogFragment.htmlのAlert Dialog見出しを参照してください)。問題はコールバックメソッドです。提供された例では、アクティビティの2つのメソッドにハードコードされています。私は2つの問題がある、私はこのプロセスに関与することを望んでいない、私は作成する別のAlertDialogのための別のコールバックメソッドが必要です。私は本当に私が作成するAlertDialogごとにハードコーディングされたコールバックで別のクラスを作成する必要はありません。

フラグメントを入れるもう1つの方法は、フラグメントマネージャが、作成プロセス中に保存された "引数"を使用して画面を回転した後に再作成される方法です。これは単純な方法でなければなりません。 。これらの引数はバンドル内に保存されますが、バンドル内にコールバックメソッドを保存できないため、フラグメントマネージャは渡されたコールバックメソッドでフラグメントを再作成できません。 AlertDialogの各タイプのハードコーディングされたコールバックメソッドを使用して表示します...これは愚かですか、ここで何かが欠落していますか? (真の)任意の助け

おかげで、 ハリー

答えて

0

呼び出すsetRetainInstanceは、あなたの実際のフラグメントのインスタンスを保存するためにFragmentManagerの原因となります。フラグメントを破棄して再作成するのではなく、同じアクティビティを新しいアクティビティに渡すだけです。

setRetainInstance(true)を使用する際に注意しなければならない主な点は、フラグメントの存続期間中にonCreateView()およびonDestroyView()に対する複数の呼び出しが異なるアクティビティに関連付けられていることを示します。したがって、たとえばonCreateView()にBroadcastReceiverを登録してonDestroy()で登録を解除すると、コードはsetRetainInstance(false)で正常に動作しますが、setRetainInstance(true)では正常に動作しません。

編集 - この回答は間違っているだけでなく、am in the discussion for the related issue

私は私が得るすべての下降音に値する。 :) setRetainInstance(true)にバグがあり、DialogFragmentのonDestroyView()内でハックしてgetDialog()。setDismissMessage(null)を呼び出すことで修正できます。

+0

しかし、提案していただきありがとうございます。提案した方法を使用しているときに画面回転後にダイアログが表示されることはありません。それはなぜ論理的には理にかなっていますが、残念ながらそれはしません。 –

+0

私のケースでは、次のコードがその仕事をすることを知っています: 'DialogFragment dialog =/*ダイアログの断片を作成する* /; FragmentTransaction ft = getFragmentManager()。beginTransaction(); dialog.show(ft、LIST_DIALOG); ' これはちょうど私が持っているいくつかのコードからリッピングされています - あなたのケースでは、AlertDialogなどを作成する必要があります。 –

1

インターフェイスを使用して、ハードコードされたコールバックを少し整理できます。

次のサンプルでは、​​私のダイアログフラグメントクラスは、Hostというインターフェイスを指定しています。このフラグメントを使用したいアクティビティは、MyAlertDialog.Hostインターフェイスを実装し、それが定義する2つのメソッドを持たなければなりません。もちろん、一般的なonOptionOneonOptionTwoの名前の代わりにonReport,onRetryを使用することができます。

import android.app.AlertDialog; 
import android.app.Dialog; 
import android.content.DialogInterface; 
import android.os.Bundle; 
import android.support.v4.app.DialogFragment; 

public class MyAlertDialog extends DialogFragment { 

    /** 
    * Host activities have to implement this interface to receive button click 
    * callbacks. 
    * 
    */ 
    public static interface Host { 
     public void onOptionOne(); 

     public void onOptionTwo(); 
    } 

    public static MyAlertDialog newInstance() { 
     return new MyAlertDialog(); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       Host host; 
       try { 
        host = (Host) getActivity(); 
       } catch (ClassCastException e) { 
        String name = getActivity().getClass().getName(); 
        throw new RuntimeException("Class " + name + " doesn't implement MyAlertDialog.Host interface"); 
       } 

       if (which == DialogInterface.BUTTON_POSITIVE) 
        host.onOptionOne(); 
       if (which == DialogInterface.BUTTON_NEGATIVE) 
        host.onOptionTwo(); 
      } 
     }; 

     return new AlertDialog.Builder(getActivity()) 
       .setMessage("Message here") 
       .setPositiveButton("Option One", clickListener) 
       .setNegativeButton("Option Two", clickListener) 
       .create(); 
    } 
} 

は具体的な活動を参照していません。アクティビティがこのダイアログを使用することを選択すると、アクティビティはその契約を実装する必要があります。それは、他の方法の代わりに、ダイアログがアクティビティと結びついて、それらにつながる場所です。