15

Activity複数のがありFragmentます。の 1 つからを表示するDialogFragmentか、別の を開きたいです。an が sを開くタスクを担当する必要があることを知っているので、代わりにいくつかのことを試しました。FragmentFragmentActivityFragment

最初
に使用getActivity()してキャストしようとしたので、でメソッドを呼び出して a をActivity表示できますが、Fragmentこれにより で依存関係が作成され、可能であれば依存関係の追加を避けたいと思いますFragmentSECOND 次に、リスナーに を表示する必要があることを通知しようとしました。そこで、リスナー インターフェイスを実装するクラスを作成しました。しかし、使用する必要があり、このインスタンスが初期化されていないため、使用しようとするとスローされるため、問題がありました。第三 に、私はそれを手に入れようとしましたActivity


ActivityFragmentActivityNew MyActivity().new Listener();ExceptiongetSupportFragmentManager()Activity


Activityリスナーを直接実装します。これは、アクティビティではなくリスナーとの依存関係のみを作成するためです。しかし今、私Activityは 2 から 4 つの異なるインターフェースを実装するところまで来ています。

したがって、私が試した方法はどれでも、レンガの壁にぶつかり、作成する必要があるかどうかわからない依存関係を作成しているようです。私はうんざりしていて、これらのオプションのいずれかを使用する必要がありますか? もしそうなら、どのオプションが最適でしょうか?どんな助けや提案も大歓迎です。

4

7 に答える 7

16

インターフェイスの作成

public interface ListenFromActivity {
    void doSomethingInFragment();
}

Activity クラスでは、ListenFromActivityインターフェイスの参照を保持します

 public ListenFromActivity activityListener;   

リスナーを設定する public メソッドを作成する

 public void setActivityListener(ListenFromActivity activityListener) {
        this.activityListener = activityListener;
    }

アクティビティ クラスにトリガー ポイントを追加します。ここでは、ユーザー インタラクションを使用しています。

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();

        if (null != activityListener) {
            activityListener.doSomethingInFragment();
        }
    }

Fragment クラスで

フラグメントにインターフェイス クラスを実装させる

public class SomeFragment extends Fragment implements ListenFromActivity

Androidスタジオは、フラグメントでインターフェースのメソッドを実装するように促します

 void doSomethingInFragment()
{//Add your code here 
}

onCreateフラグメントメソッドでこのようなアクティビティへの最後の部分のリスナーインスタンス

((ListnerActivity) getActivity()).setActivityListener(SomeFragment.this);

終わり!!。アクティビティからフラグメント メソッドを呼び出すことができるようになりました。

于 2016-11-21T07:12:25.983 に答える
11

個人的には、フラグメントは再利用可能なモジュール式のコンポーネントと考えるべきだと思います。したがって、この再利用性を提供するために、フラグメントは親のアクティビティについてあまり認識しないようにする必要があります。しかしその見返りとして、アクティビティは保持しているフラグメントについて知る必要があります。

したがって、私の意見では、非常に高度に結合されたコードを引き起こす依存性の理由から、最初のオプションを考慮すべきではありません。

2 番目のオプションについては、フラグメントは、アプリケーション フローまたは UI 関連の決定 (新しいフラグメントの表示、フラグメント固有のイベントがトリガーされたときの処理の決定など) を親アクティビティに委任できます。したがって、リスナー/コールバックはフラグメント固有である必要があるため、フラグメントで宣言する必要があります。そして、これらのフラグメントを保持するアクティビティは、これらのインターフェースを実装し、何をすべきかを決定する必要があります。

したがって、私にとっては 3 番目のオプションの方が理にかなっています。アクティビティは、特定のコールバックで何を保持し、何を行っているかという点で、より読みやすいと思います。しかし、そうです、あなたの活動は神のオブジェクトになるかもしれません。

いくつかのインターフェースを実装したくない場合は、Square のOttoプロジェクトをチェックしてみてください。基本的にイベントバスです。

于 2013-07-03T21:56:01.233 に答える
4

Fragment X から FragmentActivity にデータを渡す必要があります。FragmentActivity は、このデータを Fragment Y に渡します。これは、フラグメント クラスで定義されたインターフェイスを介して行い、onAttach() で定義されたコールバックをインスタンス化します。

これを行う方法の詳細については、こちらを参照してください 。他のフラグメントとの通信

簡単な例として、フラグメント A とフラグメント B について考えてみましょう。フラグメント A はリスト フラグメントであり、アイテムが選択されるたびに、フラグメント B に表示される内容が変更されます。

まず、フラグメント A をそのように定義します。

 public class FragmentA extends ListFragment{

   //onCreateView blah blah blah

}

そして、これがフラグメントBです

public class FragmentB extends Fragment{

 //onCreateView blah blah blah

}

そして、これが両方を管理する私の FragmentActivity です

public class MainActivity extends FragmentActivity{

//onCreate 
//set up your fragments

}

おそらく、すでにこのようなものを持っていると思いますが、FragmentA(データを取得する必要があるリストフラグメント)を変更する方法は次のとおりです。

    public class FragmentA extends ListFragment implements onListItemSelectedListener, onItemClickListener{

OnListItemSelectedListener mListener;

   //onCreateView blah blah blah



 // Container Activity must implement this interface
    public interface OnListItemSelectedListener {
    public void onListItemSelected(int position);
}


}


  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
        mListener = (OnListItemSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnListItemSelectedListener");
    }
}


  @Override 
 public void onItemClick(AdapterView<?> parent, View view, int position, long id){


 //Here's where you would get the position of the item selected in the list, and  pass    that position(and whatever other data you need to) up to the activity 
//by way of the interface you defined in onAttach

  mListener.onListItemSelected(position);


}

ここで最も重要な考慮事項は、親アクティビティがこのインターフェイスを実装していないことです。そうしないと、例外が発生します。正常に実装された場合、リスト フラグメント内の項目が選択されるたびに、Activity にその位置が通知されます。明らかに、任意の数またはタイプのパラメーターを使用してインターフェースを変更できます。この例では、整数の位置を渡しているだけです。これがちょっとした人を明確にすることを願っています、頑張ってください。

于 2013-07-03T21:58:30.803 に答える
2

あなたの2番目のオプションは正しい軌道に乗っていると思います。

フラグメントで、リスナー インターフェイスを定義します。

class MyFragment ...
{
    public interface IMyFragmentListenerInterface
    {
        void DoSomething();
    }
}

アクティビティにインターフェースを実装させます。

class MyActivity
{
    class MyListener1 implements IMyFragmentListenerInterface { ... }
}

リスナーをフラグメントに渡します。Fragment のコンストラクターで行うのが好きですが、それはフラグメントを完全に自分で管理する場合にのみ機能します。setListener代わりにメソッドをフラグメントに追加できます。

于 2013-07-03T21:29:37.730 に答える
0

疎結合を最大限に活用するには、Square の OTTO や GreenRobot の EventBus などのイベント バスを使用できます。フラグメントは、アクティビティによって処理されるイベントを発生させることができ、その逆も同様です。これの優れた点は、コンポーネント (アクティビティ、フラグメント) が互いに関係なく、インターフェイスやコールバックを宣言する必要がないことです。

私はすべてのプロジェクトで使用していますが、堅牢であり、パフォーマンスへの影響はほとんどありません (通常の状態では)。

于 2013-11-21T13:00:45.190 に答える
0

このようなことを試しましたか(フラグメントから):

FragmentTransaction ft = 
    getActivity().getSupportFragmentManager().beginTransaction();
Fragment prev = 
    getActivity().getSupportFragmentManager().findFragmentByTag("some_name");
if (prev != null) {
    ft.remove(prev);
}
ft.addToBackStack(null);

DialogFragment dialogFragment = DialogFragmentClass.newInstance();
dialogFragment.show(ft, "some_name");

教えてください、乾杯。

于 2013-07-03T21:57:17.863 に答える