6

I have found the android data binding with a custom view explanation, but this doesn't work for me because I do not understand this very well and also I have a little bit different case.

My idea: I need canvas so I can draw something on it. I have made a class(CustomView) that extends the View class. In CustomView class I have made instance of service that is in charge of drawing, and in the overridden onDraw method I passed canvas to service class so the app can draw.

The problem: In activity I have used setContentView(new CustomView());, but this will not work if I want to use MVVM design pattern. How can I separate these and make it to work with MVVM data binding? I do not understand how and where to setup CustomView so it can be fetched/binded by view with data binding?

Please bear with me, I am new to android and do not have enough experience. Thanks :)

svarog
  • 688
  • 1
  • 12
  • 29

1 Answers1

7

I propose this solution:

Activity.java

package com.example.myapplication;

import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.example.myapplication.databinding.ActivityBinding;

import java.util.Arrays;

public class Activity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        //Do magic with binding
        ActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity);
        CustomViewModel viewModel = new CustomViewModel();
        binding.setVariable(BR.vm, viewModel);
        binding.executePendingBindings();

        //Fill model
        viewModel.backgroundFill.set(Color.WHITE);
        viewModel.setCircleModels(Arrays.asList(new CircleModel(0, 0), new CircleModel(200, 400)));
    }
}

CustomView.java

package com.example.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import java.util.Collections;
import java.util.List;

public class CustomView extends View
{
    private Paint mPaint = new Paint();
    private int backgroundFill;
    private List<CircleModel> circleModels = Collections.emptyList();

    public CustomView(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);

        mPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        mPaint.setColor(backgroundFill);
        canvas.drawPaint(mPaint);

        mPaint.setColor(Color.BLUE);
        for(CircleModel model : circleModels)
            canvas.drawCircle(model.getX(), model.getY(), 100, mPaint);
    }

    public void setBackgroundFill(@ColorInt int backgroundFill)
    {
        this.backgroundFill = backgroundFill;
    }

    public void setCircles(List<CircleModel> circles)
    {
        circleModels = circles;
    }
}

CustomViewModel.java

package com.example.myapplication;

import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.databinding.ObservableInt;

import java.util.ArrayList;
import java.util.List;

public class CustomViewModel extends BaseObservable
{
    public final ObservableInt backgroundFill = new ObservableInt();
    @Bindable
    private List<CircleModel> circleModels = new ArrayList<>();

    public List<CircleModel> getCircleModels()
    {
        return circleModels;
    }

    public void setCircleModels(List<CircleModel> circleModels)
    {
        this.circleModels = circleModels;
        notifyPropertyChanged(BR.circleModels);
    }
}

CircleModel.java

public class CircleModel
{
    private int x;
    private int y;

    public CircleModel(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int getX() { return x; }

    public int getY() { return y; }
}

activity.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="vm"
            type="com.example.myapplication.CustomViewModel" />
    </data>

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.example.myapplication.CustomView
            android:id="@+id/canvas"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:backgroundFill="@{vm.backgroundFill}"
            app:circles="@{vm.circleModels}"/>
            <!--Setters in CustomView-->
            <!--app:backgroundFill="@{vm.backgroundFill}"-->
            <!--app:circles="@{vm.circleModels}"-->

    </android.support.design.widget.CoordinatorLayout>
</layout>

Contact with me if need all project

  • Привет! Thank you, I will try this solution and let you know the outcome. – svarog May 22 '17 at 08:03
  • Hello Виталий, can you please give me git repo for whole project, it would be very helpful? Also, can you tell me is it ok to have instantiated objects of some drawing services inside CustomView class? Thanks – svarog May 29 '17 at 14:35
  • 1
    Hi, Hogar, link on project: https://github.com/Arigar/AndroidMVVMExample.git. I don`t understand question about "instantiated objects of some drawing services". Do you mean [android service](https://developer.android.com/guide/components/services.html), or something else? – Виталий Махнев May 30 '17 at 15:53
  • This is very confusing me. Is this repo yours? May I ask questions there? – svarog Jun 09 '17 at 10:55
  • 1
    Yes, it's my repo. I created it specially for this question. You can ask there. – Виталий Махнев Jun 10 '17 at 07:47