【发布时间】:2017-04-14 19:34:54
【问题描述】:
我正在尝试在 MvxImageView(在 android CardView 内)上实现可触发动画,以便在卡片 ViewModel 上的属性更改时将颜色(绿色或红色)叠加到图像上。我使用 Stuart Lodge 的示例 here 创建了自定义类 DynamicImageView。
public class DynamicImageView : MvxImageView
{
public DynamicImageView(Context context) : base(context)
{
}
public DynamicImageView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public DynamicImageView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
}
protected DynamicImageView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
Drawable d = this.Drawable;
if (d != null)
{
// ceil not round - avoid thin vertical gaps along the left/right edges
int width = MeasureSpec.GetSize(widthMeasureSpec);
int height = (int)Math.Ceiling(width * (float)d.IntrinsicHeight / d.IntrinsicWidth);
this.SetMeasuredDimension(width, height);
}
else
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private ObjectAnimator colorFilterAnimation;
private string _animatingColor;
public string AnimatingColor
{
set
{
System.Diagnostics.Debug.WriteLine("Animation triggered");
if (value != _animatingColor)
{
_animatingColor = value;
colorFilterAnimation = ObjectAnimator.OfObject((ImageView)this, "colorFilter", new ArgbEvaluator(), 0, 0);
switch (value)
{
case "red":
colorFilterAnimation.SetObjectValues(0, new Color(100, 0, 0, 80).ToArgb());
System.Diagnostics.Debug.WriteLine("Starting Red Animation");
break;
case "green":
colorFilterAnimation.SetObjectValues(0, (int)Color.Green);
System.Diagnostics.Debug.WriteLine("Starting Green Animation");
break;
}
colorFilterAnimation.SetDuration(1000);
colorFilterAnimation.Start();
}
}
}
}
在此控件的 ViewModel 中,我还定义了匹配属性,遵循标准 MvvmCross 表示法:
private string _animatingColor;
public string AnimatingColor {
get
{
return _animatingColor;
}
set
{
_animatingColor = value;
Debug.WriteLine("AnimatingColor set to " + value);
RaisePropertyChanged(() => AnimatingColor);
}
}
此属性在单击卡片时发生更改,当我单击时,我确实看到属性 set 内的调试打印,但它似乎没有触发控件内的 set AnimatingColor全部。控件在axml中引用正常:
<DynamicImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
local:MvxBind="ImageUrl 'http:'+Profile.Headshot.Url; AnimatingColor .AnimatingColor" />
值得一提的是,imageUrl 确实正确绑定,并在 ViewModel 中更改 Url 时按预期更新。此外,Debug.PrintLine("Animation triggered") 确实会在创建卡片时打印,但不会在 ViewModel 上更改属性时打印。
【问题讨论】:
-
您是否为
AnimatingColor编写了自定义绑定?如果可以,可以发一下吗? -
因为我不知道你这么说是什么意思 - 我希望这可能是我的问题所在。但是,根据 n+1 天的示例,由于我只是为
AnimatingColor使用了一个字符串,我不知道我需要更多的东西来将字符串绑定到添加的属性。编辑:当然,我对这种绑定的工作方式有错误的可能性持非常开放的态度,我只是想确保我提供了尽可能多的信息。 -
与
local:MvxBind绑定的属性需要为它们编写一个custom binding 才能执行任何操作。您使用的 ImageUrl 绑定按预期工作的原因是因为在 MvvmCross 本身的某个地方已经为它编写了一个目标绑定。如果您检查您的调试输出窗口,是否有关于 MvvmCross 无法为AnimatingColor绑定控件的消息? -
这就是让我失望的原因 - 我没有看到任何消息。我将再次运行并通过输出查看,但这也是我的第一个想法。编辑:AnimatingColor 确实没有绑定错误。它似乎可以识别该属性并适当地绑定来自 ViewModel 的字符串。我将尝试实现自定义绑定,看看会发生什么。
-
已实现但没有变化 - 仍然没有绑定错误,但在按下项目时没有动画。不过,VM 的属性正在发生变化。
标签: c# xamarin data-binding xamarin.android mvvmcross