2016-09-30 8 views
1

私はMVPパターンを使用してアンドロイドアプリケーションを作成しています。依存性注入のために私はdagger 2を使います。私は、 "view"インターフェースを実装する抽象的なフラグメントを持っており、Model-View-Presenterのビューにしています。アンドロイドを表示するプレゼンターのサブクラスを注入

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()); 
    } 
} 
} 

状況に応じて、私はこの抽象ビューの2つのサブクラスのいずれかを使用します。ご覧のとおり、「DetailsPresenter」をビューに挿入します。 DetailsPresenterは、2つのサブクラス(ビューの各サブクラスに1つ)を持つ抽象クラスです。

ただし、ビューがMovieDetailFragmentの場合はMovieDetailPresenterを持ち、ShowDetailFragmentの場合はShowDetailPresenterを持つ必要があります。

私の質問は、どのような種類のビューを確認し、適切なDetailsPresenterを提供するためのロジックを実装する必要がありますか?私はDaggerモジュールでそれを行う必要があります(おそらく、プレゼンターを返すメソッド)?私は断片そのものでそれをするべきですか?

これは私のモジュールです:

@Module 
public class ConfigPersistentModule { 

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

は私を助けてください。

答えて

1

あなたは子クラスであなたのプレゼンターを注入しなければならない(MovieDetailFragment & ShowDetailFragment)とあなたのモジュールに次の2つが以下のようなモジュールを提供しておく必要があります。

@Module 
public class ConfigPersistentModule { 

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

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

、その後、あなたの子供のクラスは次のように挿入します

をMovieDetailFragmentで

@Inject ShowDetailFragment mCreditPresenter; 

:ShowDetailFragmentで

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を実装するすべてのクラスを伝える必要があります:子供たちは、それを上書きし、以下のようにするためにあなたの父クラス(MediaDetailFragment)で今

@Inject MovieDetailFragment mCreditPresenter; 
は必須であり、「getPresenter」という抽象機能を置きます彼の発表者と父親についての父はその発表者を使用します。その子どもたちのクラス(MovieDetailFragment & ShowDetailFragment)の書き込みで:

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

ふふ、最終的には私はあなたが言った、まさに実装することになりました。私はしばらく時間をかけて考え出した。あなたの答えは正しいので、+1して受け入れてください! –

+0

良いジャブ!!そのコンセプトを忘れることはないので、あなたが自分でそれを行うときは、その方が優れています。私はあなたの質問が私に考えさせたので投票をします;) –

関連する問題