2017-11-27 3 views
0

einstellen Ich bekam eine Art von einem typischen Musik-Player-Fenster, Musik spielt und Seekbar Punkt bewegt sich, während es spielt.Wie man Bindungen für Start/StopTrackingTouch für Seekbar mit MvvmCross

Ich habe es standardmäßig durchgeführt unter Verwendung mvvmcross der Eigenschaft Bindung wie hier (die durch die EventHandler Bindung geändert wird):

<SeekBar 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/playprogress" 
     local:MvxBind="Progress ValueOfTimer" 
     /> 

So, jetzt möchte ich den Benutzer in der Lage sein, um es vorwärts zu bewegen und zurück .

Ich habe versucht, es so zu binden:

public class PlayWindowViewModel : MvxViewModel<ListMenuItemDto> 
{ 

    private long _valueOfTimer; 

    public long ValueOfTimer 
    { 
     get { return _valueOfTimer; } 

     set 
     { 
      _valueOfTimer = value; 
      RaisePropertyChanged(() => ValueOfTimer); 
     } 
    } 

    //... 

    public MvxAsyncCommand<long> PlayProgressChanged 
    { 
     get { return new MvxAsyncCommand<long>(OnPlayProgressChange);} 
    } 

    private async Task OnPlayProgressChange(long progr) 
    { 
     await _playingService.SetTime((int) progr).ConfigureAwait(false); 
    } 
} 

Aber sieht aus wie es nicht funktioniert:

public class PlayWindowView : MvxActivity 
    { 

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

      var set = this.CreateBindingSet<PlayWindowView, PlayWindowViewModel>(); 

      SeekBar seek = FindViewById<SeekBar>(Resource.Id.playprogress); 

      set.Bind(seek).For("Max").To(viewModel => viewModel.MaxTimerValue); 
      set.Bind(seek).For("StopTrackingTouch").To(viewModel => viewModel.PlayProgressChanged); 
      set.Apply(); 
     } 

     protected override void OnViewModelSet() 
     { 
      SetContentView(Resource.Layout.playwindow_view); 
     } 
    } 

Ansichtsmodell Teil sieht wie folgt aus. Ich meine, es ist nicht einmal in OnPlayProgressChange. Aber in Sicht erscheint es einmal in Befehl PlayProgressChanged. Wie kann ich dieses Ereignis (und solche Ereignisse wie , StopTrackingTouch) an die Funktion binden?

P.S. nur FYI ich mit MvvmCross 5


UPD 28.11.2017

benutzerdefinierte Bindung Versuchte und sogar Progress Bindung stoped jetzt arbeiten. So sieht XAML dies wie jetzt:

<SeekBar 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/playprogress" 
     local:MvxBind="Progress ValueOfTimer, OnStopTrackingTouch PlayProgressChanged" 
     /> 

Und Binder Code hier ist

public class SeekbarStopTrackingTouchEventBinding: MvxAndroidTargetBinding 
{ 
    private readonly SeekBar _seekbar; 
    private IMvxAsyncCommand _command; 

    public SeekbarStopTrackingTouchEventBinding(SeekBar seekbar) : base(seekbar) 
    { 
     _seekbar = seekbar; 
     _seekbar.StopTrackingTouch += ViewOnStopTrackingTouch; 
    } 

    private void ViewOnStopTrackingTouch(object sender, SeekBar.StopTrackingTouchEventArgs e) 
    { 
     if (_command != null) 
     { 
      _command.Execute(e); 
     } 
    } 

    public override Type TargetType 
    { 
     get { return typeof (IMvxAsyncCommand); } 
    } 

    protected override void SetValueImpl(object target, object value) 
    { 
     _command = (IMvxAsyncCommand)value; 
    } 


    protected override void Dispose(bool isDisposing) 
    { 
     if (isDisposing) 
     { 
      _seekbar.StopTrackingTouch -= ViewOnStopTrackingTouch; 
     } 
     base.Dispose(isDisposing); 
    } 

    public override MvxBindingMode DefaultMode 
    { 
     get { return MvxBindingMode.OneWay; } 
    } 
} 

}

In Setup:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
    { 
     base.FillTargetFactories(registry); 

     registry.RegisterFactory(new MvxCustomBindingFactory<SeekBar>("OnStopTrackingTouch", (seekbar) => new SeekbarStopTrackingTouchEventBinding(seekbar))); 
    } 

UPD2

Geändert Bindung wie folgt: local:MvxBind="Progress ValueOfTimer; OnStopTrackingTouch PlayProgressChanged" (Hinweis ; hier) und Ereignis Brände jetzt, ja!

Aber jetzt ist die Sache - in binder_command ist Aufenthalte null auch nach SetValueImpl gefeuert und _command = (IMvxAsyncCommand)value; ist in Ordnung, value Punkte gefassten Ansichtsmodell Eigenschaft.

enter image description here

Wie kommt das?

UPD3

Fand heraus, es nicht object-IMvxAsyncCommand werfen können.

I festgelegt, daß durch IMvxAsyncCommand _commandIMvxAsyncCommand<SeekBar.StopTrackingTouchEventArgs> _command zu ändern;

Summiert alles in der Antwort.

Aber jetzt habe ich die Frage - was Best Practice in diesem Fall?

Antwort

0

Also ich weiß nicht, ob es ein guter Weg ist, aber für jetzt funktioniert es und ich bin irgendwie glücklich damit.

Ich hoffe, dies würde jemandem wie mir helfen.

Benutzerdefinierte Bindungen Ansatz ist hier der Schlüssel. Wirklich nützliche Dinge sind hier:

In MvvmCross how do I do custom bind properties

MvvmCross Custom Event Binding Event Args

MVVMCross Bindings in Android

Also, in meinem Fall zu App zu SeekBarOnStopTrackingTouch Ereignisse hören machen ich dies getan:

Erstellt Bindungsklasse :

public class SeekbarStopTrackingTouchEventBinding: MvxAndroidTargetBinding 
    { 
     private readonly SeekBar _seekbar; 
     private IMvxAsyncCommand<SeekBar.StopTrackingTouchEventArgs> _command; 
     private string testString; 

     public SeekbarStopTrackingTouchEventBinding(SeekBar seekbar) : base(seekbar) 
     { 
      _seekbar = seekbar; 
      _seekbar.StopTrackingTouch += ViewOnStopTrackingTouch; 
     } 

     private void ViewOnStopTrackingTouch(object sender, SeekBar.StopTrackingTouchEventArgs e) 
     { 
      if (_command != null) 
      { 
       _command.Execute(e); 
      } 
     } 

     public override Type TargetType 
     { 
      get { return typeof (IMvxAsyncCommand); } 
     } 

     protected override void SetValueImpl(object target, object value) 
     { 
      try 
      { 
       _command = (IMvxAsyncCommand<SeekBar.StopTrackingTouchEventArgs>)value; 
      } 
      catch (Exception e) 
      { 
       Log.Error("SOME BINDER FAIL\n\t" + e.Message + "\n", "SOME BINDER FAIL\n\t" + e.Message + "\n"); 
       throw; 
      } 
     } 


     protected override void Dispose(bool isDisposing) 
     { 
      if (isDisposing) 
      { 
       _seekbar.StopTrackingTouch -= ViewOnStopTrackingTouch; 
      } 
      base.Dispose(isDisposing); 
     } 

     public override MvxBindingMode DefaultMode 
     { 
      get { return MvxBindingMode.OneWay; } 
     } 
    } 

In Setup.cs diesen Code platziert:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
{ 
    base.FillTargetFactories(registry); 

    registry.RegisterFactory(new MvxCustomBindingFactory<SeekBar>("OnStopTrackingTouch", (seekbar) => new SeekbarStopTrackingTouchEventBinding(seekbar))); 
} 

Eigenschaft Prepared in meiner ViewModel und Befehl ausführen Funktion:

public IMvxAsyncCommand<SeekBar.StopTrackingTouchEventArgs> PlayProgressChanged 
    { 
     get 
     { 
      return new MvxAsyncCommand<SeekBar.StopTrackingTouchEventArgs>(OnPlayProgressChange); 
     } 
    } 

    private async Task OnPlayProgressChange(SeekBar.StopTrackingTouchEventArgs e) 
    { 
     var progr = e.SeekBar.Progress; 
     await _playingService.SetTime((int) progr).ConfigureAwait(false); 
    } 

Im Hinblick Layout innerhalb local:MvxBind verknüpfen meinen ViewModel Befehl mit evend Namen, sofern in registry.RegisterFactory in

<SeekBar 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/playprogress" 
     local:MvxBind="Progress ValueOfTimer; OnStopTrackingTouch PlayProgressChanged" 
     /> 
+0

Die Das einzige, was ich hier nicht mag, ist, dass Ihr Befehl eine nicht portierbare EventArgs-Klasse umschließt, die nur für Android verfügbar ist. Ich würde wahrscheinlich versuchen, das zu ändern. – Cheesebaron

+0

@Cheesebaron gut, wie, nur Daten übergeben, die ich brauche in einer einfachen Struktur? Oder ist es anders? – DanilGholtsman

Verwandte Themen