使用MVVM实现自定义视图

6
我找到了使用自定义视图的Android数据绑定的解释,但这对我没有用,因为我不太理解,而且我的情况有点不同。
我的想法: 我需要画布,这样我就可以在上面画东西。 我创建了一个扩展了View类的类(CustomView)。在CustomView类中,我创建了一个负责绘制的服务实例,并在重写的onDraw方法中将canvas传递给服务类,以便应用程序进行绘制。
问题: 在活动中,我使用了setContentView(new CustomView());,但如果我想使用MVVM设计模式,这将无效。 我该如何分离它们并使其与MVVM数据绑定一起工作? 我不明白如何在哪里设置CustomView,以便可以通过数据绑定的视图获取/绑定?
请原谅我,我是新手,没有足够的经验。 谢谢 :)
1个回答

7
我提出以下解决方案:
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>

如果需要整个项目,请与我联系。


你好!谢谢,我会尝试这个解决方案并告诉你结果。 - svarog
你好,Виталий,能否给我整个项目的git仓库,这将非常有帮助。另外,请问在CustomView类中实例化一些绘图服务的对象是否可以?谢谢。 - svarog
1
嗨,Hogar,项目链接:https://github.com/Arigar/AndroidMVVMExample.git。我不明白关于“某些绘图服务的实例化对象”的问题。你是指[Android服务](https://developer.android.com/guide/components/services.html),还是其他什么东西? - Виталий Махнев
这让我很困惑。这个仓库是你的吗?我可以在那里问问题吗? - svarog
1
是的,这是我的代码库。我专门为这个问题创建了它。你可以在那里提问。 - Виталий Махнев

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接