Стандарт архитектуры Android MVP для загрузки пользовательского интерфейса с классом модели, имеющим ресурс android

Я использую MVP-архитектуру в своем приложении. Моя HomeActivity содержит скользящую панель со списком, имеющим селектор, который при выборе элемента "Скользящая панель" изменил состояние значка, и я не использую селектор списка.

Я сохраняю класс модели NavItemData​​strong > для заполнения навигация и использование класса SlidingPanelItemSelector, который extends StateListDrawable генерирует соответствующий селектор для значок скользящей панели.

В архитектуре MVP у нас есть класс презентатора, который взаимодействует с моделью и генерирует вход для представлений. В моем случае , если я использую презентатор для получения данных для скользящей панели, я вызываю класс из ведущего, что использование контекста android - это хороший подход или , у нас есть альтернативное решение, которое строго следуя архитектуре MVP?

В настоящее время я использую класс ViewBinderUtilsи ввел его непосредственно в класс активности и получил список данные для раздвижной панели. Является ли это после Mvp Architcture?

SlidingPanelItemSelector.class

public class SlidingPanelItemSelector extends StateListDrawable {
    private Context mContext;

    public SlidingPanelItemSelector(Context mContext){
        this.mContext = mContext;
    }

    public StateListDrawable getHomeSelector(){
    StateListDrawable stateListDrawable = new StateListDrawable();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            stateListDrawable.addState(new int[]{android.R.attr.state_pressed},
                mContext.getDrawable(R.drawable.ic_nav_home_active));
            stateListDrawable.addState(new int[]{},mContext.getDrawable(R.drawable.ic_nav_home));
        }else{
            stateListDrawable.addState(new int[]{android.R.attr.state_pressed},
                mContext.getResources().getDrawable(R.drawable.ic_nav_home_active));
            stateListDrawable.addState(new int[]{},mContext.getResources().getDrawable(R.drawable.ic_nav_home));
        }

        return stateListDrawable;
    }
}

ViewBinderUtils.class

public class ViewDataBinderUtils {
    Context mContext;
    @Inject
    public ViewDataBinderUtils(@ActivityContext Context mContext) {
        this.mContext = mContext;
    }
    public List<SlidingPanelData> getListData(String [] titles){
        List<SlidingPanelData> items = new ArrayList<>();
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getHomeSelector(),titles[0],true));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getConfigurationSelector(),titles[1],false    ));
    items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getConfigurationSelector(),titles[2],false));
        items.add(new SlidingPanelData(true));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getQuoteSelector(),titles[3],false));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getEquipmentInventorySelector(),titles[4],false));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getCustomerSelector(),titles[5],false));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getQuoterSelector(),titles[6],false));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getSalesProgramsSelector(),titles[7],false));
        items.add(new SlidingPanelData( new SlidingPanelItemSelector(mContext).getCreditAppsSelector(),titles[8],false));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getRetailOffersSelector(),titles[9],false));
        items.add(new SlidingPanelData(true));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getPayOffersSelector(),titles[10],true));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getAlertsSelector(),titles[11],true));
        items.add(new SlidingPanelData(true));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getTermofUseSelector(),titles[12],false));
        items.add(new SlidingPanelData(new SlidingPanelItemSelector(mContext).getLegalInfoSelector(),titles[11],false));
        return items;
    }
}

Ответ 1

Презентатор должен быть изолирован от контекста, потому что единственная часть, которая должна знать об этом контексте, - это часть Вид (V). Я не очень хорошо понимаю вашу цель с этими классами, но в общем виде вы должны следовать этой логике

если я использую презентатор для получения данных для скользящей панели я am вызов класса из ведущего, использующего контекст android

Создайте интерфейс, который отвечает за управление связью между View (V) с помощью Presenter (P).

Communication.java

public interface Communication {
    void showLoading();
    void hideLoading();
    void setSlidingData(String [] titles);
}

В вашем представлении должен реализовываться этот интерфейс Comunication и есть ссылка для Presenter. И если вам нужно использовать контекст для Interactor (I), у вас должен быть класс, который управляет этим (в моем случае RequestHolder).

View.java

public View implements Communication{
    private Presenter mPresenter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
           // your view already implements the Comunication interface
           mPresenter = new Presenter(this);
        }
        (...)
       private void getData(){
         mPresenter.getData(new RequestHolder(getApplicationContext()));
       }

       @Override
       public void setSlidingData(String [] titles){
          List<SlidingPanelData> items = new ArrayList<>();
          items.add(new SlidingPanelData(new SlidingPanelItemSelector(getApplicationContext()).getHomeSelector(),titles[0],true));
       }
    }

в презентаторе есть ссылка для вашего интерфейса

Presenter.java

private Communication mView;

public Presenter(Communication view) {
    mView = view;
}

/** event to receive data from the model **/
public void onEvent(GetDataMessage event){
   mView.setSlidingData(event.getData());
} 

public void getData(final RequestHolder holder){
   new GetDataInteractor(holder);
}

RequestHolder.java

// you can put the data important to the interactor
public RequestHolder(final Context context, int accountId) {
    super(context); 
}
//getters and setters

С помощью этого вы можете получить доступ к контексту внутри вашего интерактора без концепций сопряжения


В сумме,

  • Вид является единственным, предоставляющим контекст
  • View имеет ссылку на Presenter
  • Ведущий "разговаривает" с представлением между интерфейсом

В вашем конкретном случае, почему вы не создаете Список, который нуждается в контексте в вашей части View и заполняет элементы List = new ArrayList < > (); в вашей презентационной части? с этим вы держите все изолированное