什么是 『动态数据集合』 ?简而言之,就是当集合添加、删除项目或者重置时,能提供一种通知机制,告诉UI动态更新界面。有经验的程序员脑海里迸出的第一个词就是 ObservableCollection。没错,它在WPF中盛行其道,经过它开发者能够很方便的达到动态更新界面。要在Unity 3D中使用ObservableCollection仍是有些许困难的,由于Mono并不提供ObservableCollection类。但实际上,本身动手去构建一个『动态数据集合』也非难事,核心在于怎样去传播通知。这也是本篇博客的主题。git
既然核心在于构建通知机制,谈到『通知』两字,最多见的形式就是以委托或者事件形式将消息广播给监听者。遗憾的是,.NET中常见的集合数据结构List并不支持事件的通知。因此我在自定义的ObservableList中增长OnAdd,OnRemove,OnInsert事件,当集合添加或者删除项时,能广播通知给客户端UI界面。程序员
如下图为例,当点击+时,『以数据驱动界面的形式』,动态的去更新UI界面:github
既然要以数据来驱动界面,首先咱们须要定义能存放数据的集合,它就是ObservableList,而且是实现了IList 接口:数据结构
public class ObservableList<T>:IList<T>
{
//...省略部分代码...
private List<T> _value=new List<T>();
public delegate void AddHandler(T instance);
public AddHandler OnAdd;
public delegate void InsertHandler(int index,T instance);
public InsertHandler OnInsert;
public delegate void RemoveHandler(T instance);
public RemoveHandler OnRemove;
public void Add(T item) {
_value.Add(item);
if (OnAdd != null)
{
OnAdd(item);
}
}
public bool Remove(T item) {
if (_value.Remove(item))
{
if (OnRemove != null)
{
OnRemove(item);
}
return true;
}
return false;
}
public void Insert(int index, T item) {
_value.Insert(index,item);
if (OnInsert!=null)
{
OnInsert(index, item);
}
}
}复制代码
能够看到,自定义的ObservableList实现了 IList 接口,并以泛型的形式约束了数据项类型。当添加或者删除项时,提供了以事件的形式告诉客户端UI界面 ,做为观察者的UI能够顺势作出相应的更新。ui
岔开话题说一下,为何要用泛型,这是几天前有同窗在群里问的?spa
到目前为止,咱们自定义的动态数据集合ObservableList是很是好的设计,但惟一不足的事,它不能支持初始化时通知UI界面更新。 『初始化』 这词可能有点太术语了,我翻译一下就是通常初始化一个List,咱们都是像以下方式进行:翻译
public ObservableList<FaceBox> DataSource = new ObservableList<FaceBox>
{
new FaceBox
{
Name = "Eyes",
Level = 10,
Face = "Avatar201_Face",
Badge = new Badge {Icon = "Icon_WeaponRod", ElementColor = "1CB9FFFF"}
},
new FaceBox
{
Name = "Jack",
Level = 8,
Face = "Avatar202_Face",
Badge = new Badge {Icon = "Icon_WeaponSpear", ElementColor = "FF5821FF"}
}
};复制代码
显然这即没有触发OnAdd,也没有触发OnRemove等事件,那么初始化或者重置列表时,UI界面仍是得不到更新。那咱们怎么去解决呢?还记得第一章中BindableProperty吗?对了,解决方案就是它,对列表的初始化或者重置就是对Value进行改变。而BindableProperty内部提供了对Value值改变的监听,一旦Value改变了,将消息广播出去。设计
OK,咱们加强一下ObservableList:code
public class ObservableList<T>:IList<T>
{
//省略部分代码...
public delegate void ValueChangedHandler(List<T> oldValue, List<T> newValue);
public ValueChangedHandler OnValueChanged;
//预先初始化,内置的List,防止空异常
private List<T> _value=new List<T>();
public List<T> Value
{
get { return _value; }
set
{
if (!Equals(_value, value))
{
var old = _value;
_value = value;
ValueChanged(old, _value);
}
}
}
private void ValueChanged(List<T> oldValue, List<T> newValue) {
if (OnValueChanged != null)
{
OnValueChanged(oldValue, newValue);
}
}
}复制代码
因此客户端UI界面只要对ObservableList的OnValueChanged事件进行监听,当初始化或者重置时,你也能够获得更新,演示效果以下:cdn
自定义的动态数据集合ObservableList看起来小巧,但五脏俱全,能提供通知机制,能够动态的去更新UI界面。 全部的一切都以数据的改变来驱动UI,这是很是重要的转变。因此看似代码复杂了,但实际上你只要关心数据便可。
源代码托管在Github上,点击此了解
欢迎关注个人公众号: