2016-09-30 65 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 !!当你自己做时更好,因为你永远不会忘记这个概念。我给你一票,因为你的问题让我觉得;) –