Understamding The MVVM Pattern in Android

Posted By : Rahul Baboria | 28-Feb-2018

With MVVM, the ViewModel recovers information from the Model when asked for by the View by means of information restricting system. This makes Activities and Fragments extremely lightweight and your code turns out to be effortlessly testable. How about we observe the Android MVVM design in detail now.

 

Android MVVM design

 

One of the cases in the official documentation to the information restricting help library displays an immediate authoritative of properties from User information protest format characteristics. In particular, this is the case code I need to examine:

 

 

Despite the fact that it's splendidly right to do linguistically, I'd contend against it. This rationale has a place elsewhere than to the design definition (we'll soon discover that it has a place with the ViewModel class). Setting it here makes the testing and troubleshooting of your code harder.

A superior arrangement is to receive an Android MVVM engineering design. The MVVM (Model-View-ViewModel) design abstracts the state and conduct of the View, which enables the engineer to isolate the improvement of the UI from the business rationale. This is accomplished by presenting a ViewModel layer in the middle of the View and Model, that ties to the View and responds to occasions.

The MVVM design contains three center parts, each having an unmistakable part:

  • Model: Data demonstrate speaking to the application business rationale;
  • View: The structure and appearance portrayal of the showed content;
  • ViewModel: Object connecting the two together which manages the view rationale.
  •  

Other structural examples for Android advancement

 

MVVM isn't the main structural example to be utilized for advancement in Android. The most normally utilized is presumably MVC design (regularly not in a perfect world actualized). Another approach picking up notoriety of late is MVP which is very like MVVM design as it were. We should observe what's distinctive about them.

 

MVC (Model-View-Controller)

 

MVC approach is very regular in Android advancement. It requires no extra engineering learning. Then again, it produces several lines of code in a solitary Activity or Fragment — supposed God protest. The code is muddled and unstructured which frequently prompts bugs and is hard to test.

The issue with this approach is that the Activity/Fragment classes approach each other protest and each activity is done within their code. For this situation, the Activity/Fragment goes about as a Controller(click audience members and other occasion audience members) and a Model (business rationale, association with DB and REST API) in the meantime. View layer is spoken to by the XML format documents.

 

MVP (Model-View-Presenter)

 

A case of a well-however out engineering approach in Android is the MVP design. MVP permits to isolate the Presentation layer from the business rationale. The application is isolated into three layers which would then be able to be tried autonomously.

The Presenter goes about as the center man between the View and Model. It gets information from the model and returns it in a legitimate arrangement to the View. It moreover chooses what stumbles over collaboration with the View. The View contains a reference to the Presenter and the main thing it does is calling techniques from the Presenter for every interface activity (for instance a catch click). The Model is basically a supplier of the information to show.

We might exhibit the use of Android MVVM design on the illustration application from my past post on information official. To put it plainly, the application shows a rundown of article things each containing an included picture of the article, its title, portion and two catches exploring to speculative article remarks and detail.

We alter the venture by improving the Article demonstrate information class and making another ViewModel class going about as an extension between the Model and View. The holding Activity doesn't change much as well:

 

public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        binding.contactList.setLayoutManager(layoutManager);
 
        List<Article> articles = new ArrayList<>();
        /* data filling */
 
        ArticleAdapter adapter = new ArticleAdapter(articles, this);
        binding.contactList.setAdapter(adapter);
    }
}

 

Adapter

We need to implement an adapter for the RecyclerView that uses data binding technique for each of its items.

public class ArticleAdapter extends RecyclerView.Adapter<ArticleAdapter.BindingHolder> {

    private List<Article> mArticles;
    private Context mContext;

    public ArticleAdapter(List<Article> mArticles, Context mContext) {
        this.mArticles = mArticles;
        this.mContext = mContext;
    }

    @Override
    public BindingHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ArticleItemBinding binding = DataBindingUtil.inflate(
                LayoutInflater.from(parent.getContext()),
                R.layout.article_item, parent, false);

        return new BindingHolder(binding);
    }

    @Override
    public void onBindViewHolder(BindingHolder holder, int position) {
        ArticleItemBinding binding = holder.binding;
        binding.setAvm(new ArticleViewModel(mArticles.get(position), mContext));
    }

    @Override
    public int getItemCount() {
        return mArticles.size();
    }

    public static class BindingHolder extends RecyclerView.ViewHolder {
        private ArticleItemBinding binding;

        public BindingHolder(ArticleItemBinding binding) {
            super(binding.contactCard);
            this.binding = binding;
        }
    }
}

 

Model

With the presentation of ViewModel, the Article information display class ends up lighter and loses the View-Model restricting rationale. Presently it's just a POJO (Plain Old Java Object) with a constructors and getter and setter techniques.

public class Article {

    private String title;
    private String excerpt;
    private boolean highlight;
    private String imageUrl;
    private int commentsNumber;
    private boolean read;

    /* constructor */
    /* getters and setters */
}

ViewModel

The ViewModel example of true excellence here as the center man and speaks with both Model (for our situation Article protest) and View (characterized by the design XML document). It actualizes the Observable interface by broadening the BaseObservable class and all the View-Model restricting rationale has moved into its code from the Article class:

public class ArticleViewModel extends BaseObservable {

    private Article mArticle;
    private Context mContext;

    public ArticleViewModel(Article mArticle, Context mContext) {
        this.mArticle = mArticle;
        this.mContext = mContext;
    }

    @Bindable
    public String getTitle() {
        return mArticle.getTitle();
    }

    public void setTitle(String title) {
        mArticle.setTitle(title);
        notifyPropertyChanged(BR.title);
    }

    public int getCardBackgroundColor() {
        return mArticle.isHighlight() ?
                ContextCompat.getColor(mContext, R.color.highlight) :
                Color.parseColor("#ffffffff");
    }

    public int getCommentsButtonVisibility() {
        return mArticle.getCommentsNumber() == 0 ?
                View.GONE : View.VISIBLE;
    }

    public int getCommentsNumber() {
        return mArticle.getCommentsNumber();
    }

    public String getExcerpt() {
        return mArticle.getExcerpt();
    }

    public String getImageUrl() {
        return mArticle.getImageUrl();
    }

    @BindingAdapter({"image"})
    public static void loadImage(ImageView view, String url) {
        Glide.with(view.getContext()).load(url).centerCrop().into(view);
    }

    public void setRead(boolean read) {
        // change title of already read article:
        if (read && !mArticle.isRead()) {
            setTitle("READ: " + getTitle());
        }

        mArticle.setRead(read);
    }

    public View.OnClickListener onReadMoreClicked() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "Opens article detail", Toast.LENGTH_SHORT).show();
                setRead(true);
            }
        };
    }

    public View.OnClickListener onCommentsClicked() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "Opens comments detail", Toast.LENGTH_SHORT).show();
            }
        };
    }
}

 

The clearer partition of View and Model layers in Android MVVM example can be watched for instance in the getCommentsButtonVisibility technique. Beforehand, the catch perceivability rationale has been a piece of the View (characterized in XML). Presently the perceivability is settled on in ViewModel and can be effectively refactored and tried. Moreover, we never again need to reference the View class as a variable from the format record.

 

Thanks.

 

 

 

 

About Author

Author Image
Rahul Baboria

Rahul Baboria is having good knowledge over Android Application.

Request for Proposal

Name is required

Comment is required

Sending message..