2017-04-20 24 views
0

我在Xamarin.Forms中製作了一個mp3播放器,其中的滑塊應該顯示時間已到,並允許跳轉到軌道中的位置。 據我所知,只有ValueChanged事件可用,不幸的副作用是每當我的計時器更新滑塊值時,我也會觸發我的player.SeekTo方法,導致播放失敗。Xamarin.Forms Slider.Clicked事件?

有沒有什麼辦法來專門選取滑塊上的觸摸事件? 如果沒有,有沒有人有任何建議如何使這項工作?

如果它是相關的,這裏是我的代碼的MainPage:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Xamarin.Forms; 

namespace MuZor 
{ 
    public partial class MainPage : ContentPage 
    { 
     public MainPage() 
     { 
      InitializeComponent(); 
      PlayButton.Clicked += PlayButton_Clicked; 
      PlaylistsButton.Clicked += PlaylistsButton_Clicked; 
      RandomButton.Clicked += RandomButton_Clicked; 
      RepeatButton.Clicked += RepeatButton_Clicked; 
      ChoiceButton.Clicked += ChoiceButton_Clicked; 
      PreviousButton.Clicked += PreviousButton_Clicked; 
      NextButton.Clicked += NextButton_Clicked; 
      TimeSlider.ValueChanged += TimeSlider_ValueChanged; 

      MessagingCenter.Subscribe<Interfaces.IAudioPlayer>(App.player, "PlayerPrepared", (args) => 
      { 
       System.Diagnostics.Debug.WriteLine("Message received"); 
       PlayerPrepared(); 
      }); 
     } 

     private void TimeSlider_ValueChanged(object sender, ValueChangedEventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine("Slider value changed, value = " + e.NewValue + "(int = " + (int)e.NewValue); 
      //App.player.SeekTo((int)e.NewValue); 
     } 

     private void NextButton_Clicked(object sender, EventArgs e) 
     { 
      if (!App.settings.RandomOn && App.settings.CurrentTrack < App.playlist.Count - 1) 
      { 
       Play((int)App.settings.CurrentTrack + 1); 
      } 
     } 

     private void PreviousButton_Clicked(object sender, EventArgs e) 
     { 
      if (!App.settings.RandomOn && App.settings.CurrentTrack > 0) 
      { 
       Play((int)App.settings.CurrentTrack - 1); 
      } 
     } 

     private void ChoiceButton_Clicked(object sender, EventArgs e) 
     { 
     } 

     private void RepeatButton_Clicked(object sender, EventArgs e) 
     { 
     } 

     private void RandomButton_Clicked(object sender, EventArgs e) 
     { 
     } 

     private void PlaylistsButton_Clicked(object sender, EventArgs e) 
     { 
     } 

     private void PlayButton_Clicked(object sender, EventArgs e) 
     { 
      if (App.settings.IsPaused || App.player.IsPlaying()) 
      { 
       App.player.PauseResume(); 
       if (App.settings.IsPaused) 
       { 
        UnPause(); 
       } 
       else 
       { 
        Pause(); 
       } 
      } 
      else 
      { 
       int trackToplay = App.settings.CurrentTrack != null ? (int)App.settings.CurrentTrack : 0; 
       Play(trackToplay); 
      } 
     } 

     private void Play(int currentTrack) 
     { 
      HelperClasses.SettingsHelper.SaveCurrentTrack(currentTrack); 
      App.player.LoadAndPlay(App.playlist[currentTrack].Path); 
     } 

     private void Pause() 
     { 
      HelperClasses.SettingsHelper.SavePausedState(true); 
      Device.BeginInvokeOnMainThread(() => 
      { 
       PlayButton.Text = "Play"; 
      }); 
     } 

     private void UnPause() 
     { 
      HelperClasses.SettingsHelper.SavePausedState(false); 
      Device.BeginInvokeOnMainThread(() => 
      { 
       PlayButton.Text = "Pause"; 
      }); 
      StartTimer(); 
     } 

     private void StartTimer() 
     { 
      double position; 
      Device.StartTimer(new TimeSpan(0, 0, 1),() => 
      { 
       position = App.player.GetCurrentPosition(); 
       TimeSpan runTime = TimeSpan.FromMilliseconds(position); 
       Device.BeginInvokeOnMainThread(() => 
       { 
        TimeLabel.Text = runTime.ToString(@"mm\:ss"); 
        TimeSlider.Value = position; 
       }); 
       if (App.player.IsPlaying()) 
        return true; 
       else 
        return false; 
      }); 
     } 

     private void PlayerPrepared() 
     { 
      var totalDurationInMS = App.player.GetDuration(); 
      TimeSlider.Maximum = totalDurationInMS; 
      TimeSlider.Minimum = 0; 
      TimeSpan totalDuration = TimeSpan.FromMilliseconds(totalDurationInMS); 
      Device.BeginInvokeOnMainThread(() => 
      { 
       RemainingTimeLabel.Text = totalDuration.ToString(@"mm\:ss"); 
       TimeLabel.Text = "00:00"; 
      }); 
      UnPause(); 
     } 
    } 
} 

回答

0

我想我已經找到了解決辦法。由於valuechanged事件同時包含舊值和新值,因此如果差值爲負數或大於2,我將僅觸發SeekTo。

相關問題