Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MVP architecture standard for loading UI with Model class having android resource

I am following MVP architecture in my application. My HomeActivity contains a Sliding Panel with list icon having selector that is upon selecting the Sliding Panel item the icon state is changed and i am not using any list selector.

I am keeping a model class NavItemData for populating the navigation drawer and using a class SlidingPanelItemSelector that extends StateListDrawable generates the appropriate selector for the sliding panel icon.

In MVP architecture we have a presenter class that communicates with the model and generates the input for views. In my case if am using the presenter for getting the data for Sliding Panel i am calling a class from presenter that using android context is that's a good approach, or we are having any alternative solution that strictly following MVP architecture?

Currently i am using a ViewBinderUtils class and injected it directly to the activity class and gets the list of data for Sliding Panel. Is it following 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;
    }
}
like image 400
Sunny Avatar asked Apr 19 '16 05:04

Sunny


People also ask

What is MVP architecture in Android?

MVP (Model — View — Presenter) architecture is one of the most popular architecture patterns and is valid in organizing the project. MVP (Model — View — Presenter) comes into the picture as an alternative to the traditional MVC (Model — View — Controller) architecture pattern.

What is MVP architecture pattern?

MVP is a user interface architectural pattern engineered to facilitate automated unit testing and improve the separation of concerns in presentation logic: The model is an interface defining the data to be displayed or otherwise acted upon in the user interface.

What is MVP and MVVM in Android?

MVP(Model View Presenter) MVVM(Model View ViewModel) It resolves the problem of having a dependent View by using Presenter as a communication channel between Model and View. This architecture pattern is more event-driven as it uses data binding and thus makes easy separation of core business logic from the View.

What is difference between MVP MVC Mvvm in Android?

MVC: The View functions independently and has no information about the controller. MVP: The View holds the presenter's knowledge in this software architecture. MVVM: The view holds references to the ViewModel in this architecture.


1 Answers

The presenter should be isolated from context stuff, because the only part that should know about the context is the View(V) part. I didn't understand well your goal with this classes, but in generic way you should follow this logic

if am using the presenter for getting the data for Sliding Panel i am calling a class from presenter that using android context

Create a interface that is responsible to manage the communication between the View (V) with Presenter (P).

Communication.java

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

Your View should implement this interface Comunication, and has a reference for the Presenter. And if you need to use the context for an Interactor (I), you should have a class that manages this (in my case 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));
       }
    }

in presenter has a reference for your interface

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

With this you can access to the context inside your interactor, without mix concepts


In sum,

  • View is the only one that provides context
  • View has a reference to the Presenter
  • Presenter "talks" with View between a Interface

In your specific case, why you don't create the List that needs the context in your View part and fills List items = new ArrayList<>(); in your presenter part? with this you keep everything isolated

like image 79
rafaelasguerra Avatar answered Sep 27 '22 16:09

rafaelasguerra