Skip to main content

Android MVVM (Model View ViewModel) Design Pattern

DataBinding Pdf Link:- https://drive.google.com/open?id=1uL0xK9EktcEWOke5vqUqp-rgqpA1ARR3

DataBinding References : - https://www.youtube.com/watch?v=v4XO_y3RErI

Steps for applying MVVM design pattern to Android Project 


1 ) Applying the changes in build.gradle (App Level) file

     android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.credencys.databindingwithrecyclerview"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

// This we have to include.

    dataBinding{
        enabled = true
    }
}

2 ) Changes in layout file of acivity/fragment.

      Put your all existing code of your acticity/fragment in between <layout>......</layout> tag

       
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <import type="codingwithmitch.com.databindinggettingstarted.util.StringUtil"/>
        <import type="codingwithmitch.com.databindinggettingstarted.util.BigDecimalUtil"/>
        <import type="android.view.View"/>
        <variable            name="product"            type="codingwithmitch.com.databindinggettingstarted.models.Product"/>
        <variable            name="quantity"            type="int"/>
        <variable            name="quantityDialogInterFace"            type="codingwithmitch.com.databindinggettingstarted.QuantityDialogInterface"/>
    </data>
    <RelativeLayout        xmlns:android="http://schemas.android.com/apk/res/android"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@color/White">

        <LinearLayout            xmlns:android="http://schemas.android.com/apk/res/android"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical"            android:padding="10dp"            android:background="@color/White">

            <RelativeLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginRight="10dp"                android:layout_marginEnd="10dp"                android:layout_marginTop="5dp">

                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:textSize="10sp"                    android:textColor="@color/DarkGrey"                    android:text="@{StringUtil.convertIntToString(product.num_ratings)}"                    android:id="@+id/num_ratings"                    android:layout_alignParentEnd="true"                    android:layout_alignParentRight="true"                    android:layout_centerVertical="true"/>


                <RatingBar                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    style="?attr/ratingBarStyleSmall"                    android:theme="@style/RatingBar"                    android:scaleX="1.2"                    android:scaleY="1.2"                    android:numStars="5"                    android:rating="@{product.rating.floatValue()}"                    android:id="@+id/rating"                    android:isIndicator="true"                    android:layout_toLeftOf="@+id/num_ratings"                    android:layout_marginRight="10dp"                    android:layout_centerVertical="true"/>

            </RelativeLayout>

            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:id="@+id/title"                android:textColor="@color/Black"                android:text="@{product.title}"                android:textSize="14sp"                android:layout_marginTop="5dp"/>

            <RelativeLayout                android:layout_width="match_parent"                android:layout_height="200dp"                android:layout_marginTop="10dp">


                <ImageView                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:scaleType="fitCenter"                    android:layout_centerHorizontal="true"                    android:layout_centerVertical="true"                    android:id="@+id/image"                    app:imageUrl="@{product.image}"                    />

            </RelativeLayout>

            <LinearLayout                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:orientation="horizontal"                android:layout_marginTop="15dp"                >

                <ImageView                    android:layout_width="14sp"                    android:layout_height="14sp"                    android:src="@drawable/ic_dollor_sign_red"/>

                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:textSize="16sp"                    android:textColor="@color/red2"                    android:text="@{product.hasSalePrice() ? BigDecimalUtil.getValue( product.sale_price) : BigDecimalUtil.getValue( product.price) }"                    android:id="@+id/price"/>


                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:textSize="10sp"                    android:textColor="@color/DarkGrey"                    android:text="@{BigDecimalUtil.getValue( product.price)}"                    android:visibility="@{product.hasSalePrice() ? View.VISIBLE:View.INVISIBLE   }"                    android:id="@+id/original_price"                    android:layout_marginLeft="10dp"                    android:background="@drawable/strike_through"/>

            </LinearLayout>

            <RelativeLayout                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:padding="10dp"                android:background="@drawable/grey_rounded_button"                android:layout_marginTop="13dp"                android:id="@+id/quantity_button"                android:onClick="@{()-> quantityDialogInterFace.inflateQuantityDialog()}"                >

                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:textSize="12sp"                    android:textColor="@color/Black"                    android:text="@{StringUtil.getQuantityString(quantity)}"                    android:id="@+id/quantity"/>

                <ImageView                    android:layout_width="15dp"                    android:layout_height="15dp"                    android:src="@drawable/ic_up_down_arrows"                    android:layout_toRightOf="@id/quantity"                    android:layout_centerVertical="true"                    android:layout_marginLeft="5dp"                    />


            </RelativeLayout>


            <RelativeLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:padding="12dp"                android:layout_marginTop="13dp"                android:background="@drawable/orange_rounded_button"                android:id="@+id/add_to_cart">

                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:textSize="14sp"                    android:textColor="@color/Black"                    android:text="Add to Cart"                    android:id="@+id/text_add_to_cart"                    android:layout_centerHorizontal="true"                    android:layout_centerVertical="true"/>

            </RelativeLayout>
        </LinearLayout>
    </RelativeLayout>
</layout>

3 ) Then after open your mainactivity/fragment

    MainAcitivity.java
   
package codingwithmitch.com.databindinggettingstarted;
import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import codingwithmitch.com.databindinggettingstarted.databinding.ActivityMainBinding;
import codingwithmitch.com.databindinggettingstarted.models.Product;
import codingwithmitch.com.databindinggettingstarted.util.ProductsValues;

public class MainActivity extends AppCompatActivity implements QuantityDialogInterface {

    private Product mProducts;
    private Activity mActivity;
    // For DataBinding    private ActivityMainBinding mActivityMainBinding;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivity=MainActivity.this;
        // Set layout file from the databinding        mActivityMainBinding= DataBindingUtil.setContentView(mActivity,R.layout.activity_main);
        setsData();
    }

    /**     * Sets Data From the model to view     */    private void setsData()
    {
        ProductsValues productsValues =new ProductsValues();
        mProducts= productsValues.PRODUCTS[0];
        mActivityMainBinding.setProduct(mProducts);
        mActivityMainBinding.setQuantityDialogInterFace((QuantityDialogInterface)mActivity);
    }

    @Override    public void inflateQuantityDialog() {
        ChooseQuantityDialog mChooseQuantityDialog=new ChooseQuantityDialog();
        mChooseQuantityDialog.show(getSupportFragmentManager(),getString(R.string.dialog_choose_quantity));
    }

    @Override    public void setQuantity(int quantity) {
        mActivityMainBinding.setQuantity(quantity);
    }
}

4 ) Model Class

    Product.java

package codingwithmitch.com.databindinggettingstarted.models;
import android.os.Parcel;

import java.math.BigDecimal;


public class Product {

    private static final String TAG = "Product";

    private String title;
    private String description;
    private int image;
    private BigDecimal price;
    private BigDecimal sale_price;
    private int num_ratings;
    private BigDecimal rating;
    private int serial_number;


    public Product(String title, String description, int image, BigDecimal price, BigDecimal sale_price, int num_ratings, BigDecimal rating, int serial_number) {
        this.title = title;
        this.description = description;
        this.image = image;
        this.price = price;
        this.sale_price = sale_price;
        this.num_ratings = num_ratings;
        this.rating = rating;
        this.serial_number = serial_number;
    }

    public Product() {

    }

    protected Product(Parcel in) {
        title = in.readString();
        description = in.readString();
        image = in.readInt();
        num_ratings = in.readInt();
        serial_number = in.readInt();
    }


    public boolean hasSalePrice(){
        double salePrice = sale_price.doubleValue();
        if(salePrice > 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public String getNumberRatingsString(){
        return ("(" + getNum_ratings() + ")");
    }

    public static String getTAG() {
        return TAG;
    }

    public int getSerial_number() {
        return serial_number;
    }

    public void setSerial_number(int serial_number) {
        this.serial_number = serial_number;
    }

    public int getNum_ratings() {
        return num_ratings;
    }

    public void setNum_ratings(int num_ratings) {
        this.num_ratings = num_ratings;
    }

    public BigDecimal getRating() {
        return rating;
    }

    public void setRating(BigDecimal rating) {
        this.rating = rating;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public BigDecimal getSale_price() {
        return sale_price;
    }

    public void setSale_price(BigDecimal sale_price) {
        this.sale_price = sale_price;
    }
}

5 ) Util Classes

    a ) BigDecimalUtil.java

        package codingwithmitch.com.databindinggettingstarted.util;
        import java.math.BigDecimal;
        import java.text.DecimalFormat;


        public class BigDecimalUtil {

               public static String getValue(BigDecimal value){
               DecimalFormat df = new DecimalFormat("###,###,###.00");
               return String.valueOf(df.format(value));
        }
        /*            For rating bar (actual rating)         */        public static float getFloat(BigDecimal value){
            return value.floatValue();
        }
     } 

     b ) ProductValues.java

package codingwithmitch.com.databindinggettingstarted.util;
import java.math.BigDecimal;
import java.util.HashMap;

import codingwithmitch.com.databindinggettingstarted.R;
import codingwithmitch.com.databindinggettingstarted.models.Product;

public class ProductsValues {

    public Product[] PRODUCTS = {RED_LAMP, YELLOW_LAMP, BLUE_MUG, WHITE_MUG, RED_MUG, BLACK_HAT, BLUE_HAT, WHITE_HAT, ORANGE_HAT,
    WHITE_SHIRT_MALE, WHITE_SHIRT_FEMALE, BLACK_SHIRT_FEMALE, BLACK_SHIRT_MALE, GREY_FIDGET_SPINNER, GREEN_FIDGET_SPINNER, ICELAND_PICTURE    , ICEY_COAST_PICTURE, HAVASU_FALLS_PICTURE, FRANCE_MOUNTAINS_PICTURE, GREEN_HILLS_PICTURE};


    public HashMap<String, Product> PRODUCT_MAP = new HashMap<>();

    public ProductsValues() {
        for(Product product : PRODUCTS){
            PRODUCT_MAP.put(String.valueOf(product.getSerial_number()), product);
        }

    }

    public static final Product RED_LAMP = new Product("Red Lamp", "Red colored lamp, perfect for lighting up a room " +
            "and matching any red furniture.", R.drawable.red_lamp, new BigDecimal(10.99), new BigDecimal(9.50), 161,
            new BigDecimal(4.5), 1515611);

    public static final Product YELLOW_LAMP = new Product("Yellow Lamp", "Yellow colored lamp, perfect for lighting up a room " +
            "and matching any Yellow furniture.", R.drawable.yellow_lamp, new BigDecimal(11.99), new BigDecimal(0), 6,
            new BigDecimal(5), 7725277);

    public static final Product BLUE_MUG = new Product("Blue Coffee Mug", "Blue Coffee Mug for drinking coffee. 100% ceramic.",
            R.drawable.blue_mug, new BigDecimal(5.99), new BigDecimal(0), 66, new BigDecimal(3.5), 2141515);

    public static final Product WHITE_MUG = new Product("White Coffee Mug", "White Coffee Mug for drinking coffee. 100% ceramic.",
            R.drawable.white_mug, new BigDecimal(6.99), new BigDecimal(0), 7, new BigDecimal(4), 9704833);

    public static final Product RED_MUG = new Product("Red Coffee Mug Red", "Red Coffee Mug for drinking coffee. 100% ceramic.",
            R.drawable.red_mug, new BigDecimal(8.99), new BigDecimal(0), 157, new BigDecimal(4.5), 9377376);

    public static final Product BLACK_HAT = new Product("Black Baseball Hat", "Black Baseball Hat made of 100% authentic " +
            "baseball hat material.",
            R.drawable.black_hat, new BigDecimal(20.99), new BigDecimal(0), 121, new BigDecimal(3.5), 6626622);

    public static final Product BLUE_HAT = new Product("Blue Baseball Hat", "Blue Baseball Hat made of 100% authentic " +
            "baseball hat material.",
            R.drawable.blue_hat, new BigDecimal(22.99), new BigDecimal(0), 67, new BigDecimal(4.5), 7837367);

    public static final Product WHITE_HAT = new Product("White Baseball Hat", "White Baseball Hat made of 100% authentic " +
            "baseball hat material.",
            R.drawable.white_hat, new BigDecimal(18.99), new BigDecimal(15.99), 88, new BigDecimal(2.5), 7695085);

    public static final Product ORANGE_HAT = new Product("Orange Baseball Hat", "Orange Baseball Hat made of 100% authentic " +
            "baseball hat material.",
            R.drawable.orange_hat, new BigDecimal(23.99), new BigDecimal(0), 23, new BigDecimal(4), 9084728);

    public static final Product WHITE_SHIRT_FEMALE = new Product("White Shirt", "White T-Shirt made of 100% cotton. Made for " +
            "females.", R.drawable.white_shirt_female, new BigDecimal(25.99), new BigDecimal(0), 98, new BigDecimal(5)
            , 7265405);

    public static final Product WHITE_SHIRT_MALE = new Product("White Shirt", "White T-Shirt made of 100% cotton. Made for " +
            "males.", R.drawable.white_shirt_male, new BigDecimal(26.99), new BigDecimal(0), 11, new BigDecimal(3)
            , 9575721);

    public static final Product BLACK_SHIRT_FEMALE = new Product("Black Shirt", "Black T-Shirt made of 100% cotton. Made for " +
            "females.", R.drawable.black_shirt_female, new BigDecimal(25.99), new BigDecimal(0), 51, new BigDecimal(4.5)
            , 5776336);

    public static final Product BLACK_SHIRT_MALE = new Product("Black Shirt", "Black T-Shirt made of 100% cotton. Made for " +
            "males.", R.drawable.black_shirt_male, new BigDecimal(26.99), new BigDecimal(0), 616, new BigDecimal(5)
            , 1408483);

    public static final Product GREY_FIDGET_SPINNER = new Product("Grey Fidget Spinner", "Grey Fidget Spinner. High quality" +
            " bearing for long spin time. Light and portable.", R.drawable.fidget_spinner_grey, new BigDecimal(100), new BigDecimal(59.99)
            , 37, new BigDecimal(4.5), 8830303);

    public static final Product GREEN_FIDGET_SPINNER = new Product("Green Fidget Spinner", "Green Fidget Spinner. High quality" +
            " bearing for long spin time. Light and portable.", R.drawable.fidget_spinner_green, new BigDecimal(100), new BigDecimal(0)
            , 3, new BigDecimal(4), 9082727);

    public static final Product ICELAND_PICTURE = new Product("Picture of Water in Iceland", "Beautiful picture of Iceland and its " +
            "cold waters.", R.drawable.foggy_iceland, new BigDecimal(189.50), new BigDecimal(100), 43,
            new BigDecimal(4.8), 6638393);

    public static final Product FRANCE_MOUNTAINS_PICTURE = new Product("Picture of the Mountains in France", "Here is an incredible picture" +
            " of the mountains in France.", R.drawable.france_mtn, new BigDecimal(356), new BigDecimal(315), 22,
            new BigDecimal(3.2), 8093475);

    public static final Product GREEN_HILLS_PICTURE = new Product("Picture of green hills in GreenLand", "A calming image of a sunset in " +
            "Greenland.", R.drawable.green_hills, new BigDecimal(99), new BigDecimal(50), 79,
            new BigDecimal(4.1), 1485032);

    public static final Product HAVASU_FALLS_PICTURE = new Product("A Very Famous Picture of Havasu Falls", "Check out this famous picture " +
            "of Havasu Falls.", R.drawable.havasu_falls, new BigDecimal(76), new BigDecimal(0), 81,
            new BigDecimal(4.9), 8041414);

    public static final Product ICEY_COAST_PICTURE = new Product("An Image of the Icy Coast of Iceland", "Looking at this picture practically " +
            "makes you shiver! But it makes me appreciate warm weather.", R.drawable.icedfglrjioz, new BigDecimal(120), new BigDecimal(0), 37,
            new BigDecimal(3.3), 1145614);
}

       d ) StringUtil.java

           package codingwithmitch.com.databindinggettingstarted.util;


           public class StringUtil {

           public static String getQuantityString(int quantity){
                  return ("Qty: " + String.valueOf(quantity));
           }

           public static String convertIntToString(int value){
                  return ("("+String.valueOf(value)+")");
           }
         }

6 ) ChooseQuantityDialog.java

package codingwithmitch.com.databindinggettingstarted;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;

import codingwithmitch.com.databindinggettingstarted.databinding.DialogChooseQuantityBinding;


public class ChooseQuantityDialog extends DialogFragment {

    private static final String TAG = "ChooseQuantityDialog";

    // data binding    DialogChooseQuantityBinding mBinding;

    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinding = DialogChooseQuantityBinding.inflate(inflater);
        mBinding.listView.setOnItemClickListener(mOnItemClickListener);
        mBinding.closeDialog.setOnClickListener(mCloseDialogListener);

        return mBinding.getRoot();
    }

    public AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {
        @Override        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            Log.d(TAG, "onItemSelected: selected: " + adapterView.getItemAtPosition(i));

            QuantityDialogInterface quantityDialogInterface=(QuantityDialogInterface)getActivity();
            quantityDialogInterface.setQuantity(Integer.parseInt((String)adapterView.getItemAtPosition(i)));
            getDialog().dismiss();
        }
    };

    public View.OnClickListener mCloseDialogListener = new View.OnClickListener() {
        @Override        public void onClick(View view) {
            getDialog().dismiss();
        }
    };
}

7 ) Interface QuantityDialogInterface.java

package codingwithmitch.com.databindinggettingstarted;

public interface QuantityDialogInterface {
    void inflateQuantityDialog();
    void setQuantity(int quantity);
}
8 ) dialog_choose_quantity.xml

<?xml version="1.0" encoding="utf-8"?><layout xmlns:app="http://schemas.android.com/apk/res-auto">
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"                  android:orientation="vertical"                  android:layout_width="170dp"                  android:layout_height="wrap_content"        android:background="@drawable/grey_rounded_background">

        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:background="@drawable/grey_rounded_button"            android:padding="5dp">

            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:textSize="16sp"                android:textColor="@color/Black"                android:textStyle="bold"                android:text="@string/dialog_quantity_title"                android:layout_centerVertical="true"                android:layout_marginLeft="10dp"/>


            <RelativeLayout                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:padding="10dp"                android:id="@+id/close_dialog"                android:layout_alignParentRight="true"                android:layout_marginRight="10dp"                android:layout_centerVertical="true">

                <ImageView                    android:layout_width="20dp"                    android:layout_height="20dp"                    android:src="@drawable/ic_x_black"                    android:layout_centerInParent="true"                    />

            </RelativeLayout>

        </RelativeLayout>

        <ListView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:entries="@array/quantity_array"            android:id="@+id/list_view">
        </ListView>

    </LinearLayout>
</layout>

9 ) GlideBlidingAdapters.java

package codingwithmitch.com.databindinggettingstarted.databinding;

import android.content.Context;
import android.databinding.BindingAdapter;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;

import codingwithmitch.com.databindinggettingstarted.R;

public class GlideBlidingAdapters
{
    @BindingAdapter("imageUrl")

    public static void setImageUrl(ImageView view,int imageUrl)
    {
        Context context=view.getContext();

        RequestOptions requestOptions=new RequestOptions()
                                      .placeholder(R.drawable.ic_launcher_background)
                                      .error(R.drawable.ic_launcher_background);

        Glide.with(context)
                .setDefaultRequestOptions(requestOptions)
                .load(imageUrl)
                .into(view);
    }

    public static void setImageUrl(ImageView view,String imageUrl)
    {
        Context context=view.getContext();

        RequestOptions requestOptions=new RequestOptions()
                .placeholder(R.drawable.ic_launcher_background)
                .error(R.drawable.ic_launcher_background);

        Glide.with(context)
                .setDefaultRequestOptions(requestOptions)
                .load(imageUrl)
                .into(view);
    }
}

Comments

Popular posts from this blog

Post data with retrofit

1 ) Retrofit Client Class public class RetrofitClient { private static final String AUTH = "Basic " + Base64. encodeToString (( "belalkhan:123456" ).getBytes(), Base64. NO_WRAP ); private static final String BASE_URL = "http://simplifiedlabs.xyz/MyApi/public/" ; private static RetrofitClient mInstance ; private Retrofit retrofit ; private RetrofitClient() { OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor( new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request original = chain.request(); Request.Builder requestBuilder = original.newBuilder() .addHeader( "Authorization" , AUTH ) .meth...

Complex Retrofit Class With Database

URL:-  http://www.mocky.io/v2/ 5b936d6f33000011002061d3 1 )   Create   RetrofitClient(Base URL Class) import retrofit2.GsonConverterFactory; import retrofit2.Retrofit; public class RetrofitClient { //http://www.mocky.io/v2/5b936d6f33000011002061d3 public static final String API_BASE_URL = "http://www.mocky.io/v2/" ; public static Retrofit retrofit = null ; public static Retrofit getApiClient() { if ( retrofit == null ) { retrofit = new Retrofit.Builder().baseUrl( API_BASE_URL ).addConverterFactory(GsonConverterFactory . create ()).build(); } return retrofit ; } } 2 ) Create Retrofit ApiInterface Class(End URL Class) import com.example.discusit.complexretrofitdemo.model.Data; import retrofit2.Call; import retrofit2.http. GET ; public interface ApiInterface { @GET ( "5b936d6f33000011002061d3" ) Call<Data> getData(); } 3 ) Create Require Model Clas...