6

Đối với một bình thường (đoạn phi lồng nhau) tôi sử dụng phương pháp sau đâyLàm thế nào để tiêm phụ thuộc vào phân đoạn android lồng nhau?

1) tạo ra phụ thuộc (...) phương pháp để thiết lập phụ thuộc đoạn của

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

2) trong hoạt động MyFragment mẹ của onAttachFragment() phương pháp tôi chỉ cung cấp phụ thuộc cho mảnh

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

đối với đoạn lồng nhau không có nhiều onAttachFragment đoạn gọi. Cung cấp phụ thuộc cho đoạn chỉ để cung cấp phụ thuộc cho đoạn lồng có vẻ rất cồng kềnh. Vậy làm thế nào tôi có thể cung cấp phụ thuộc cho nó?

+0

Sử dụng dagger2? Nó được thiết kế để quản lý những thứ như thế này –

+0

Mimmo Grottoli, tôi biết về dagger2. Nhưng nó chỉ là một thư viện để loại bỏ mã boilerplate của tiêm phụ thuộc. Luôn luôn có cách để tiêm phụ thuộc bởi constructor hoặc phương pháp đặc biệt. – wilddev

+0

Một nhà xây dựng cho các mảnh vỡ hoặc hoạt động đưa vào một số phụ thuộc?Tất nhiên bạn có thể thử, nhưng cuối cùng bạn sẽ thấy rằng dao găm hoặc dao găm 2 là những điều tốt nhất mà bạn có thể tự phát triển (ít nhất, điều này đúng với tôi) –

Trả lời

1

Chỉ cần giữ logic thứ bậc, và nó phải được một cái gì đó như thế này:

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

Rất lạ khi tiêm phụ thuộc vào MyFragment, bởi vì nó không cần chúng. MyFragment không phụ thuộc vào deps. – wilddev

+0

Điểm của câu hỏi là gì? –

+0

Iliiaz Akhmedov, MyFragment không phụ thuộc vào deps, nhưng MyNestedFragment có! Vì vậy, thông qua deps để MyFragment là antipattern. – wilddev

2

Nếu MyFragment phụ thuộc vào MyNestedFragment, và MyNestedFragment phụ thuộc vào Deps; nó sau đó MyFragment cũng phụ thuộc vào Deps. Tất nhiên, không có cá thể nào của MyNestedFragment tồn tại khi Activity.onAttachFragment() được gọi, vì vậy bạn sẽ phải đợi cho đến sau khi bạn đã tăng bố cục trong MyFragment.onCreateView() trước khi cung cấp MyNestedFragment với các phụ thuộc của nó.

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) { 
      ... 
     } 
    } 

    ... 
} 

Nếu tất cả điều này có vẻ lộn xộn một chút, đó là vì Fragments không phải POJO bạn chỉ có thể kết nối một cách tùy ý. Vòng đời của họ phải được quản lý bởi FragmentManagers lồng nhau. Nếu bạn tạo các đoạn của bạn theo chương trình thay vì sử dụng phần tử >, bạn sẽ có quyền kiểm soát nhiều hơn đối với vòng đời của mình với chi phí phức tạp hơn.

Nếu bạn muốn đối xử với Android như một container IoC, sau đó RoboGuice có thể là những gì bạn đang tìm kiếm:

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

Just do it tắt bối cảnh đó sẽ là một hoạt động. Tạo một getter cho các phụ thuộc vào hoạt động của bạn. Các mảnh vỡ có quyền truy cập vào hoạt động gốc cho dù có lồng nhau hay không. Truyền bối cảnh và sau đó gọi trình thu thập để nhận các phụ thuộc trong hoạt động lồng nhau.

+0

Để thêm tín dụng tạo ra một giao diện ComponentProvider và có hoạt động của bạn thực hiện nó, cho thấy một phương thức getComponent. GetContext nên được truyền đến giao diện chứ không phải là một hoạt động cụ thể cho phép tái sử dụng các đoạn trên các hoạt động. – FriendlyMikhail

2

Bạn cố gắng đặt phụ thuộc, khi các mảnh được đính kèm. Thay vì điều này, hãy cố gắng để có được sự phụ thuộc từ các mảnh khi cần thiết. Có một ví dụ:

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."); 
     } 
    } 
} 

Tất nhiên, bạn có thể làm cho phương pháp riêng biệt cho DEPS get trong hoạt động (như getDepsForMyFragmentgetDepsForMyNestedFragment).

Các vấn đề liên quan