Xamarin.Android MVVM灯ListView绑定

屏幕截图_2015-10-02-08-41-47.

这是前一个的扩展 邮政 介绍如何为控件创建绑定。在这篇文章中,我们将研究如何将集合绑定到Android 列表显示 并每次在视图模型中从集合中添加或删除项目时更新视图。

项目设置

添加MVVM灯库 Laurent Bugnion. 通过Nuget到Xamarin.android项目:

PM> Install-Package MvvmLight

然后在视图模型中创建一个 观察到 这将表示整个列表。

public ObservableCollection<Person> People { get; private set; }

要设置列表,我们可以使用InitialIzer方法,该方法当前在单独的线程中生成。现在,当列表很大时,这只有意义即,如果我们开始抬起号码,那么这个创作的处理器沉重。因此,随着基础知识,所有集合都让我们关注活动。

活动

设置绑定的理想场所是在 oncreate. 方法,因此通过覆盖它,我们可以设置列表的绑定。 Android ListView的数据容器是我们通常必须手动创建的适配器。由于MVVM灯,我们可以在一行代码中执行此操作:

protected override async void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);

    SetContentView(Resource.Layout.Main);

    await Vm.InitAsync();
    PeopleListView.Adapter = Vm.People.GetAdapter(GetPersonView);
    // ...
}

getpersonview. 参数是创建显示行时会调用的方法。在此方法中,行的数据将相应地填充到UI字段中:

private View GetPersonView(int position, Person person, View convertView)
{
    View view = convertView ?? LayoutInflater.Inflate(Resource.Layout.RowPerson, null);

    var firstName = view.FindViewById<TextView>(Resource.Id.FirstName);
    var lastName = view.FindViewById<TextView>(Resource.Id.LastName);

    firstName.Text = person.FirstName;
    lastName.Text = person.LastName;

    return view;
}

请注意,Yyy参数可能包含可以重用的行。由于在用户滚动到远处的时间之后,只有一行数量可以显示一定程度的行。然后将这些行传递为参数YYY,然后不是NULL,并且可以使用新数据更新字段。导致较小的存储空间,在内存受限的移动设备上总是良好的。

看法

布局很简单。为了活动简单 linearlayout. 与其中的ListView一起使用:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/People" />
</LinearLayout>

该行包含两个 文本域 用于显示第一个和姓氏的人。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp">
    <TextView
        android:text="Michael"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/FirstName"
        android:layout_margin="5dp" />
    <TextView
        android:text="Westen"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/LastName"
        android:layout_margin="5dp" />
</LinearLayout>

行布局然后膨胀 getpersonview. method.

从列表视图中添加和删除人员

添加和删​​除集合的人现在真的很简单。所以我们需要扩展我们的视图是两个按钮:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/AddButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/AddPerson" />
        <Button
            android:id="@+id/RemoveButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/RemovePerson" />
    </LinearLayout>
    <!-- ... -->
</LinearLayout>

然后将它们在视图模型中的活动中接线。

protected override async void OnCreate(Bundle bundle)
{
    // ...

    AddPersonButton.SetCommand("Click", Vm.AddPersonCommand);
    RemovePersonButton.SetCommand("Click", Vm.RemovePersonCommand);
}

在视图模型中,我们只需有两个在构造函数中初始化的继电器命令:

public MainViewModel()
{
    AddPersonCommand = new RelayCommand(AddPerson);
    RemovePersonCommand = new RelayCommand(RemovePerson);
}

public RelayCommand AddPersonCommand { get; set; }
public RelayCommand RemovePersonCommand { get; set; }

调用命令时,将从可观察集合中添加或删除一个人,这将自动将其传播到演示文稿中 列表显示.

#

了解活动生命周期

注意当涉及MVVM灯提供的适配器时,内存泄漏可能有可能使用内部设置适配器创建的内部设置。当活动被摧毁并重新创建时。打开设备并更改方向时。在内部,活动将被挂钩到视图模型中可观察集合的事件。即使在创建新活动之后,此连接将持续。因此,旧活动仍然悬挂,因为它总是在视图模型中挂钩到可观察的集合。这就是为什么在每个观点模型中 initasync. 可观察的集合将用新实例替换。这将清理路径并允许不再使用的活动收集垃圾。

public async Task InitAsync()
{
    if (People != null)
    {
        // Prevent memory leak in Android
        var peopleCopy = People.ToList();
        People = new ObservableCollection<Person>(peopleCopy);
        return;
    }

    People = new ObservableCollection<Person>();

    var people = await InitPeopleList();
    People.Clear();
    foreach (var person in people)
    {
        People.Add(person);
    }
}

结论

在此帖子中,我们显示了我们如何将集合绑定到ListView,以及如何将集合的更新自动传播到视图。此外,我们看到如何正确处理活动的生命周期而不产生内存泄漏。由于MVVM光线,在Android应用程序中显示集合的复杂性大大减少了。

整个样本都可以找到 GitHub..

这篇文章之前发布在 诺勒工程博客.

Updated: