6

は、I)は、(MyFragment親の活性onAttachFragmentにフラグメントの依存関係ネストされたアンドロイド・フラグメントに依存性を注入する方法は?通常の(非ネストされた断片)について

class MyFragment extends MyFragment { 
     void dependencies(Deps deps); 
} 

2)を設定するために、以下のアプローチ

1)依存関係を作成(...)メソッドを使用しこの方法は、私はちょうどと呼ばれるもうonAttachFragmentフラグメントはありませんネストされたフラグメントのためのフラグメント

class MyActivity{ 
    void onAttachFragment(Fragment f){ 
     ((MyFragment)f).dependencies(deps); 
    } 
} 

の依存関係を提供しています。 フラグメントの依存関係を提供することは、ネストされたフラグメントの依存関係を提供するためだけに非常に厄介なようです。だから私はそれにどのように依存関係を与えることができますか?

+0

dagger2を使用しますか?この種のものを管理するように設計されています –

+0

Mimmo Grottoli、私はdagger2について知っています。しかし、それは依存性注入の定型コードを排除する単なるライブラリです。依存関係をコンストラクタや特別なメソッドで注入する方法は常に存在するはずです。 – wilddev

+0

依存関係を挿入するフラグメントまたはアクティビティのコンストラクタ?もちろん、試してみることもできますが、最終的には、daggerやdagger2があなた自身で開発することができる最良のものです(少なくとも、これは私には当てはまります) –

答えて

1

だけ階層論理を維持し、それがこのようなものでなければなりません:

class MyActivity{ 
    void onAttachFragment(Fragment f){ 
     ((MyFragment)f).dependencies(deps); 
    } 
} 

class MyFragment extends MyFragment { 
     void dependencies(Deps deps) { 
      //TODO: do dependencies of my fragment before 
      ((MyNestedFragment)childF).nestedDependencies(deps); 
      //TODO: do dependencies of my fragment after 
     } 
} 

class MyNestedFragment extends MyNestedFragment { 
     void nestedDependencies(Deps deps); 
} 
+0

依存関係を必要としないため、依存関係をMyFragmentに注入するのは非常に奇妙です。 MyFragmentはdepsに依存しません。 – wilddev

+0

質問のポイントは何ですか? –

+0

Iliiaz Akhmedov、MyFragmentはdepsに依存しませんが、MyNestedFragmentはそうです!したがって、MyFragmentにdepsを渡すことは反パターンです。 – wilddev

2

MyFragmentMyNestedFragmentに依存し、MyNestedFragmentDepsに依存している場合。 MyFragmentもまたDepsに依存します。もちろん、のインスタンスは存在しません。Activity.onAttachFragment()が呼び出されたときには、MyNestedFragmentの依存関係を提供する前に、レイアウトをMyFragment.onCreateView()に膨張させておく必要があります。

public class MyActivity { 

    ... 

    void onAttachFragment(Fragment f){ 
     ((MyFragment)f).dependencies(deps); 
    } 

    public static class MyFragment extends Fragment { 

     private Deps deps; 

     void dependencies(Deps deps) { 
      this.deps = deps; 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

      // <fragment> element in fragment_main layout has 
      // android:tag set to nested_fragment 
      ((MyNestedFragment)getChildFragmentManager() 
       .findFragmentByTag("nested_fragment")) 
       .dependencies(this.deps); 

      return rootView; 
     } 
    } 

    public static class MyNestedFragment extends Fragment { 

     void dependencies(Deps deps) { 
      ... 
     } 
    } 

    ... 
} 

このすべてが少し厄介と思われる場合、それはフラグメントがPOJOではないので、あなただけのいくつかの任意の方法で配線することができます。ライフサイクルは、ネストされたFragmentManagersによって管理される必要があります。 <フラグメント>要素を使用するのではなく、プログラムでフラグメントを作成すると、複雑さを犠牲にしてライフサイクル全体をより詳細に制御できます。

あなたはIoCコンテナのようなアンドロイドを扱いたい場合は、RoboGuiceは、あなたが探しているものかもしれ:

public class MyActivity extends roboguice.activity.RoboFragmentActivity { 

    ... 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     // This only needs to be called once for the whole app, so it could 
     // be in the onCreate() method of a custom Application subclass 
     RoboGuice.setUseAnnotationDatabases(false); 

     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 
    } 

    public static class MyNestedFragment extends Fragment { 

     @Inject 
     private Deps deps; 

     @Override 
     public void onAttach(Activity activity) { 
      super.onAttach(activity); 
      // this isn't necessary if you extend RoboFragment 
      roboguice.RoboGuice.getInjector(activity).injectMembers(this); 
     } 

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

      //This would not even be possible in the previous example 
      // because onCreateView() is called before dependencies() 
      // can be called. 
      deps.method(); 

      View rootView = inflater.inflate(R.layout.fragment_nested, container, false); 
      return rootView; 
     } 
    } 
} 

@Singleton 
public class Deps { 
    public void method() { 
     System.out.println("Deps.method()"); 
    } 
} 
5

だけの活動になります文脈をそれを行います。あなたの活動に依存するゲッターを作成します。フラグメントは、ネストされているかどうかにかかわらず、親アクティビティにアクセスできます。コンテキストをキャストし、ゲッターを呼び出してネストされたアクティビティの依存関係を取得します。

+0

余分なクレジットを作成するには、インターフェイスComponentProviderを作成し、アクティビティでそれを実装します。 getContextは、アクティビティ間でフラグメントを再利用できる特定のアクティビティではなく、インターフェイスにキャストする必要があります。 – FriendlyMikhail

2

フラグメントが添付されている場合、依存関係を設定しようとします。代わりに、必要に応じてフラグメントから依存関係を取得してみてください。例があります:もちろん

public class MyActivity extends Activity { 

    public Deps getDepsForFragment(Fragment fragment) { 
     if (fragment instanceof MyFragment) { 
      return depsForMyFragment; 
     } else if (fragment instanceof MyNestedFragment) { 
      return depsForMyNestedFragment; 
     } else { 
      return null; 
     } 
    } 
} 

public class MyFragment extends Fragment { 

    private Deps deps; 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     try { 
      MyActivtiy myActivity = (MyActivtiy) context; 
      deps = myActivity.getDepsForFragment(this); 
     } catch (ClassCastException e) { 
      throw new ClassCastException("This fragment attached to an activity which can't provide the required dependencies."); 
     } 
    } 
} 

// this is the same as the MyFragment 
public class MyNestedFragment extends Fragment { 

    private Deps deps; 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     try { 
      MyActivtiy myActivity = (MyActivtiy) context; 
      deps = myActivity.getDepsForFragment(this); 
     } catch (ClassCastException e) { 
      throw new ClassCastException("This fragment attached to an activity which can't provide the required dependencies."); 
     } 
    } 
} 

は、あなたが(getDepsForMyFragmentgetDepsForMyNestedFragmentなど)の活動のGet DEPSために分離方法を行うことができます。