Проблемы с переходом на MVP
Есть приложение, которое получает данные с сайта и заполняет ими RecyclerView. Хочу перейти на MVP. Прочел множество статей и знаю в теории что это за паттерн. Но не могу применить на практике. Подскажите где ошибся?
MvpView (Глобальный)
public interface MvpView {
void showProgress(boolean visibility);
}
ListCatalog (для списка)
public interface ListCatalog extends MvpView {
void getCategories(MainModel mainModel);
void getList(Context context, String sortBy, String sortType);
}
Presenter
public class ListCatalogPresenter extends MvpPresenter<ListCatalog> {
private MainModel mainModel;
public void getCategories() {
String sortBy = "popular", sortType = "desc";
MyApp.getHoffApi().getModel(sortBy, sortType).enqueue(new Callback<MainModel>() {
@Override
public void onResponse(Call<MainModel> call, Response<MainModel> response) {
mainModel = response.body();
getView().getCategories(mainModel);
}
@Override
public void onFailure(Call<MainModel> call, Throwable t) {
}
});
}
Адаптер
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.CategoryViewHolder> {
Context context;
MainModel mainModel;
public CategoryAdapter(Context context, MainModel mainModel) {
this.context = context;
this.mainModel = mainModel;
}
@NonNull
@Override
public CategoryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new CategoryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_category_recycler, parent, false));
}
@Override
public void onBindViewHolder(@NonNull CategoryViewHolder holder, int position) {
holder.getHolder(position);
}
@Override
public int getItemCount() {
return mainModel.getRelatedCategories().size();
}
public class CategoryViewHolder extends RecyclerView.ViewHolder {
TextView nameCategory;
public CategoryViewHolder(@NonNull View itemView) {
super(itemView);
nameCategory = itemView.findViewById(R.id.name_category);
}
public void getHolder(int position) {
nameCategory.setText(mainModel.getRelatedCategories().get(position).getName());
}
}
}
В MainActivity
ListCatalogPresenter presenter;
presenter.getCategories();
Ошибка
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.idrisov.hoff.mvp.listcatalog.ListCatalogPresenter.getCategories()' on a null object reference
Ответы (1 шт):
Я не вижу вашего кода в Activity, но из ошибки есть вполне очевидный вывод: "Вы не создаете экземпляр ListCatalogPresenter".
Все что вам нужно сделать это создать его экземпляр: можно просто через
ListCatalogPresenter presenter = new ListCatalogPresenter();
Если вы используете какой-либо DI то можно прописать его зависимость в модуле.
UPD:
Для того чтоб Presenter знал о существовании вашей View вы должны в него положить ее экземпляр. Обычно в Presenter-е делается пару методов:
public void attach(MvpView view) {
this.view = view;
}
public void detach() {
view = null;
}
и в самой View в onCreate()/onDestroy() (хотя тут можно и другие колбеки взять, но важно чтоб они были зеркальны) вызываются attach/detach.
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
presenter.attach(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detach();
}
Ну и важный момент в том, что до того как вы вызовете attach вы не должны использовать Presenter т.к. там будет view = null