2016-09-30 78 views
1

我正在創建一個使用MVP模式的android應用程序。對於依賴注入,我使用匕首2.我有一個抽象片段,它實現了「視圖」接口,使其成爲模型視圖展示器中的視圖。注入演示者子類查看android

public abstract class MediaDetailFragment extends Fragment implements DetailsMvpView { 
private static final String RESOURCE = "resource"; 
private static final String POSTER_SIZE = "w342/"; 


@Inject DetailPresenter mDetailPresenter; 
@Inject CreditPresenter mCreditPresenter; 
@BindView(R.id.media_image_flipper) ControllableFlipper mImageFlipper; 
@BindView(R.id.keyword_recyclerview) RecyclerView mKeywordRecyclerView; 
@BindView(R.id.title_textview) TextView mTitleTextView; 
@BindView(R.id.overview_content_textview) TextView mOverviewTextView; 
@BindView(R.id.cast_recyclerview) CreditRecyclerView mCastRecyclerView; 
@BindView(R.id.crew_recyclerview) CreditRecyclerView mCrewRecyclerView; 
@BindView(R.id.empty_view) TextView mRecyclerviewEmpty; 
@BindView(R.id.button_share) ImageButton mShare; 
@BindView(R.id.button_trailers) ImageButton mTrailers; 
@BindView(R.id.button_reviews) ImageButton mReviews; 
@BindBool(R.bool.isTablet) boolean mIsTablet; 

@OnClick(R.id.button_share) public void shareMedia(View view) { 
    startActivity(new Intent(Intent.ACTION_SEND) 
      .putExtra(Intent.EXTRA_TEXT, getActivity().getString(R.string.base_youtube_url) 
        + POSTER_SIZE + mMedia.posterPath() + "\n\n" 
        + mMedia.title() + "\n\n" + mMedia.overview()) 
      .setType("text/plain")); 
} 

@OnClick(R.id.button_trailers) public void requestTrailers(View view) { 
    mDetailPresenter.loadMovies(mMedia.id()); 
} 

@OnClick(R.id.button_reviews) public void requestReviews(View view) { 
    if (NetworkUtil.isNetworkConnected(getContext())) { 
     ((FragmentHandler) getActivity()).onReviewsRequested(mMedia); 
    } else { 
     ViewUtil.displayNoNetworkSnackbar(getActivity()); 
    } 
} 

private Media mMedia; 
private DisplayMetrics mDisplayMetrics = new DisplayMetrics(); 
private OnGlobalLayoutListener mListener; 

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mMedia = getArguments().getParcelable(RESOURCE); 
} 

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

    View rootView = inflater.inflate(R.layout.media_details_fragment, container, false); 

    ((BaseActivity) getActivity()).activityComponent().inject(this); 
    ButterKnife.bind(this, rootView); 

    getActivity().getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics); 

    mTitleTextView.setText(mMedia.title()); 
    mOverviewTextView.setText(mMedia.overview()); 

    mKeywordRecyclerView.setAdapter(new KeywordAdapter(getContext())); 
    mCastRecyclerView.setAdapter(R.layout.item_credit_normal, mRecyclerviewEmpty); 
    mCrewRecyclerView.setAdapter(R.layout.item_credit_normal, mRecyclerviewEmpty); 

    mListener =() -> rootView.post(() -> { 
     if (mIsTablet) { 
      mImageFlipper.getLayoutParams().height = 
        ViewUtil.setHeightForAspectRatio(rootView.getWidth(), ViewUtil.STANDARD); 
     } else { 
      mImageFlipper.getLayoutParams().height = 
        ViewUtil.setHeightForAspectRatio(mDisplayMetrics.widthPixels, ViewUtil.STANDARD); 
     } 
     rootView.getViewTreeObserver().removeOnGlobalLayoutListener(mListener); 
    }); 
    rootView.getViewTreeObserver().addOnGlobalLayoutListener(mListener); 

    return rootView; 
} 

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

    mDetailPresenter.attachView(this); 
    mDetailPresenter.loadImages(mMedia.id()); 
    mDetailPresenter.loadKeywords(mMedia.id()); 

    mCreditPresenter.attachCastView(mCastRecyclerView); 
    mCreditPresenter.attachCrewView(mCrewRecyclerView); 
    mCreditPresenter.loadCredits(mMedia.id()); 
} 

@Override 
public void onStop() { 
    mDetailPresenter.detachView(); 
    mCreditPresenter.detachCastView(); 
    mCreditPresenter.detachCrewView(); 
    super.onStop(); 
} 

@Override 
public void showImages(String image) { 
    mImageFlipper.addImagePath(image); 
} 

@Override 
public void showKeywords(List<String> keywords) { 
    ((KeywordAdapter) mKeywordRecyclerView.getAdapter()).setKeywords(keywords); 
} 

@Override 
public void showVideos(List<Video> videos) { 
    TrailerDialogFragment.newInstance(videos).show(getFragmentManager(), null); 
} 

@Override 
public void showError() { 
    if (!NetworkUtil.isNetworkConnected(getContext())) { 
     ViewUtil.displayNoNetworkSnackbar(getActivity()); 
    } 
} 
} 

根據情況我會使用這個抽象視圖的兩個子類之一。正如你所看到的,我在視圖中注入了一個「DetailsPresenter」。 DetailsPresenter也是一個具有兩個子類(視圖的每個子類都有一個子類)的抽象類。

但是,如果視圖是MovieDetailFragment,它應該有一個MovieDetailPresenter,並且如果它是一個ShowDetailFragment,它應該有一個ShowDetailPresenter。

我的問題是:我應該在哪裏實現檢查它是什麼樣的視圖並提供正確的DetailsPresenter的邏輯?我應該在Dagger模塊中做(可能在返回演示者的方法中)?我應該在片段本身做到嗎?

這是我的模塊:

@Module 
public class ConfigPersistentModule { 

    @Provides 
    DetailPresenter provideDetailPresenter(DataManager dataManager) { 
     return new MovieDetailPresenter(dataManager); 
    } 
} 

請幫助我。

回答

1

必須注入的子類的主持人(MovieDetailFragment & ShowDetailFragment)和你的模塊中,你需要有兩個提供模塊象下面這樣:

@Module 
public class ConfigPersistentModule { 

@Provides 
MovieDetailFragment provideDetailPresenter(DataManager dataManager) { 
    return new MovieDetailPresenter(dataManager); 
} 

@Provides 
ShowDetailFragment provideDetailPresenter(DataManager dataManager) { 
    return new ShowDetailFragment(dataManager); 
} 
} 

,然後在子類中注入這樣的:

在ShowDetailFragment:

@Inject ShowDetailFragment mCreditPresenter; 
在MovieDetailFragment

@Inject MovieDetailFragment mCreditPresenter; 
現在

在你的父類(MediaDetailFragment)提出了一個名爲「getPresenter」抽象函數是強制性的孩子來覆蓋它,象下面這樣:

public abstract class MediaDetailFragment extends Fragment implements DetailsMvpView { 
    private mDetailPresenter; 

    public abstract DetailPresenter getPresenter(); 

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     this.mDetailPresenter = getPresenter(); 
     ... 
     ... 
    } 
    ... 
    ... 
} 

現在實行MediaDetailFragment每堂課要告訴父親關於他的主持人和父親使用那個主持人。所以在少兒班(MovieDetailFragment & ShowDetailFragment)寫:

@Override 
public DetailPresenter getPresenter() 
{ 
    return mCreditPresenter; 
} 
+0

呵呵,我終於結束了實現你說的到底是什麼。花了一段時間才弄清楚。由於你的回答是正確的,+1並接受! –

+0

好jub !!當你自己做時更好,因爲你永遠不會忘記這個概念。我給你一票,因爲你的問題讓我覺得;) –