stackyyflow
stackyyflow

Reputation: 763

Dagger 2 Android Fragment

My presenter is null while trying to use Dagger 2 in Fragments for MVP architecture. I would like to know the correct way of implementing presenters in Fragments. Here is my code:

FeedFragment.java

public class FeedFragment extends Fragment implements FeedFragmentView,
        FeedAdapter.OnCapsuleClickListener {

    private OnFragmentInteractionListener mListener;
    private Unbinder unbinder;

    @Inject FeedFragmentPresenter mFeedFragmentPresenter;
    @Inject FeedAdapter mFeedAdapter;

    @BindView(R.id.news_feed_list) RecyclerView mRecyclerView;

    public FeedFragment() {
        // Required empty public constructor
    }

    public static FeedFragment newInstance() {
        return new FeedFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
        unbinder = ButterKnife.bind(this, rootView);

        mRecyclerView.setAdapter(mFeedAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(
                getActivity(), LinearLayoutManager.VERTICAL, false));
        mFeedFragmentPresenter.attachView(this);    // NULL ERROR HERE
        mFeedFragmentPresenter.loadCapsules();

        return rootView;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
        mFeedFragmentPresenter.detachView();
    }

    @Override
    public void show(List<CapsuleWrapper> capsules) {
        mFeedAdapter.setCapsules(capsules);
        mFeedAdapter.notifyDataSetChanged();
    }

    @Override
    public void showError() {
        DialogFactory.networkErrorDialog(getActivity(),
                R.string.dialog_title_network_error)
                .show();
    }
}

FeedFragmentPresenter.java

@ConfigPersistent
public class FeedFragmentPresenter extends BasePresenter<FeedFragmentView> {

    private final DataManager mDataManager;
    private Disposable mDisposable;

    @Inject
    public FeedFragmentPresenter(DataManager dataManager) {
        mDataManager = dataManager;
    }

    @Override
    public void attachView(FeedFragmentView view) {
        super.attachView(view);
    }

    @Override
    public void detachView() {
        super.detachView();
        if (mDisposable != null) mDisposable.dispose();
    }

    public void load() {

    }

}

BasePresenter.java

public class BasePresenter<T extends View> implements Presenter<T> {

    private T mView;

    @Override
    public void attachView(T view) {
        mView = view;
    }

    @Override
    public void detachView() {
        mView = null;
    }

    public boolean isViewAttached() {
        return mView != null;
    }

    public T getView() {
        return mView;
    }

    public void checkViewAttached() {
        if (!isViewAttached()) throw new ViewNotAttachedException();
    }

    public static class ViewNotAttachedException extends RuntimeException {
        public ViewNotAttachedException() {
            super("Please call Presenter.attachView(View) before" +
                    " requesting data to the Presenter");
        }
    }
}

FeedFragmentView.java

public interface FeedFragmentView extends View {

    void show(List<CapsuleWrapper> capsules);

    void showEmpty();

    void showError();

}

FragmentComponent.java

@PerFragment
@Component( modules = {FragmentModule.class}, dependencies = {ApplicationComponent.class} )
public interface FragmentComponent {

    void inject(FeedFragment fragment);

}

FragmentModule.java

@Module
public class FragmentModule {

    @Provides
    @PerFragment
    public FeedFragmentPresenter providePresenter(DataManager dataManager){
        return new FeedFragmentPresenter(dataManager);
    }

}

Upvotes: 0

Views: 3115

Answers (1)

Satiswar Dash
Satiswar Dash

Reputation: 73

here is the implementation showcasing dagger 2 and MVVM

If you are using fragments then don’t forget to inject your fragment instance in onAttach method.

Upvotes: 1

Related Questions