MVVM +数据绑定

时间:2018-06-27 06:10:57

标签: android mvvm android-databinding

让我们假设我有一个气象应用程序,其中我正在从数据提供者那里获取数据并将其保存在本地数据库中。现在,我有一个Repository类,其工作是根据特定条件从API或本地DB中获取数据。我有一个“设置”页面,用户选择以°F为单位显示温度,以km为单位显示距离。我从API获得的数据是温度(°C)和距离(mi)。我的View请求ViewModelRepository获取数据。 Repository获取数据并返回名为WeatherData的模型。现在,我的数据以°C和mi为单位。使用DataBinding在布局文件中导入Util类是一个好主意,其中包含帮助方法,这些方法可以根据“设置”中选择的用户来转换这些单位?还是WeatherData中应该有一些方法可以转换数据并使用数据绑定显示在视图中?还是有另一个人以正确的方式做到这一点?

2 个答案:

答案 0 :(得分:1)

这是一个有趣的问题,可能会有不同的答案,但是我会对此事发表看法。

查看ViewModels的一种方法是将其视为视图的“模型”。通过这种方式,您可以确保您的视图将非常简洁和虚假,这是理想的,因为它们很难甚至不可能被测试。而且由于VM也是视图和模型之间的层,因此它是进行数据和类型转换的理想场所。好处包括可测试性(如我所说,很难用XML验证转换逻辑)和更好的可维护性(如果出于某种原因您将来必须更改视图)。

要考虑的另一点是干净的体系结构。在干净的体系结构中,依赖关系是向内的。上层模型应映射到下层模型或从下层模型映射。在您的情况下,Repository已经达到了提供WeatherData的目的,因此它不必关心数据如何在上层使用。

为回答您的问题,我认为应该在ViewModel中,或者如果您想在不同视图中进行多次转换的情况下进一步分离,请在您的域层和ViewModel。

答案 1 :(得分:0)

因此,您要根据自己的设置来显示°C /°F和mi / km。

您可以在模型类WeatherData中使用转换逻辑

就像

class WeatherData{

    private float degrees;

    public float getCelsius(){
        //conversion
    }

    public float getFahrenheit(){
        //conversion
    }

    private float km;

    public float getKm(){
        //conversion
    }

    public float getMiles(){
        //conversion
    }

} 

在您的视图模型中,您可以拥有boolean celsius,km;之类的标志

在布局中,您可以定义这三个变量。

    <data>
        <variable
            name="celsius"
            type="Boolean"/>
        <variable
            name="km"
            type="Boolean"/>
        <variable
            name="data"
            type="WeatherData"/>
    </data>
    <TextView
        android:id="@+id/tv_distance"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{km?data.km:data.miles}" />
    <TextView
        android:id="@+id/tv_temperature"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{celsius?data.celsius:data.fahrenheit}"
        />