2017-04-14 38 views
0

我試圖在MvxImageView(在一個Android CardView內)上實現可觸發的動畫,以在卡的ViewModel上的屬性更改時將顏色(綠色或紅色)覆蓋到圖像上。我使用Stuart Lodge的示例here創建了自定義類DynamicImageView。MvvmCross自定義綁定沒有通知RaisePropertyChanged

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(); 
      } 
     } 
    } 
} 

在視圖模型的這種控制,我已經定義以及匹配性質,下列標準MvvmCross符號:

private string _animatingColor; 
    public string AnimatingColor { 
     get 
     { 
      return _animatingColor; 
     } 
     set 
     { 
      _animatingColor = value; 
      Debug.WriteLine("AnimatingColor set to " + value); 
      RaisePropertyChanged(() => AnimatingColor); 
     } 
    } 

這個屬性上點擊改變到卡上,當我點擊我看到屬性set內的調試打印,但它似乎並沒有觸發控制內的AnimatingColor的set。控制在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並正確綁定,並在網址中的視圖模型改變爲預期的更新。此外,Debug.PrintLine("Animation triggered")確實在打印卡時打印,但絕不會在ViewModel上更改屬性。

+0

您是否爲「AnimatingColor」編寫了自定義綁定?如果是這樣,你可以發佈它嗎? –

+0

因爲當你這樣說時我不知道你的意思 - 我希望這可能是我的問題所在。然而,根據n + 1天的樣本,由於我只是使用了一個字符串作爲'AnimatingColor',我不知道我需要更多的東西來綁定字符串到添加的屬性。編輯:當然,我對我錯誤地瞭解這種綁定的可能性非常開放,我只是想確保我已經儘可能地提供了儘可能多的信息。 –

+0

你用'local:MvxBind'綁定的屬性需要有一個[自定義綁定](http://slodge.blogspot.com/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html)寫給他們做任何事情。您使用的ImageUrl綁定的原因正如預期的那樣工作,因爲在MvvmCross本身的某個地方有一個目標綁定。如果你檢查你的調試輸出窗口,是否有關於MvvmCross無法將'AnimatingColor'的控件綁定的消息? –

回答

0

正如評論所示,我相信你需要爲DynamicImageView控件創建一個自定義綁定。像這樣的東西應該這樣做:

public class DynamicImageViewAnimatingColorBinding : MvxTargetBinding 
{ 
    public DynamicImageViewAnimatingColorBinding(DynamicImageView target) : base(target) 
    { 
    } 

    protected DynamicImageView View => Target as DynamicImageView; 

    public override MvxBindingMode DefaultMode => MvxBindingMode.OneWay; 

    public override Type TargetType => typeof(string); 

    public override void SetValue(object value) 
    { 
     var view = View; 
     if (view == null) 
      return; 

     view.AnimatingColor = (string) value; 
    } 
} 

然後在您安裝類,你需要註冊它,這樣MvvmCross可以使用它:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
    { 
     registry.RegisterCustomBindingFactory<DynamicImageView>(
      nameof(DynamicImageView.AnimatingColor), 
      image => new DynamicImageViewAnimatingColorBinding (image)); 

     base.FillTargetFactories(registry); 
    } 

我沒有測試此代碼,它是基於一些非常類似於iOS上使用的代碼,但它應該在Android上正常工作。希望這有助於。

+0

已實施,但沒有更改 - 仍然沒有綁定錯誤,但按下該項目時沒有動畫。雖然虛擬機的屬性正在改變。我會繼續修補,看看會發生什麼。 –

+0

也許有點基本,但是頁面的BindingContext是否設置了? –

+1

嘿,只是要在這裏做一個facepalm,併爲浪費你的時間而道歉。我沒有提到(閱讀:我沒有意識到)我的CardView被用作ListView中模板的事實。問題是我沒有使用OvservableCollection,所以屬性更改大概不會滲透。我現在正在工作。感謝你的幫助;您的澄清問題絕對有助於我以更高效的方式檢查我的代碼,以發現潛在的問題。乾杯! –

0

James Mundy的問題讓我意識到潛在的問題是我沒有在列表中使用ObservableCollection,所以底層ViewModel的更改沒有反映在UI中。