Xamarin.Forms Slider.Clicked事件?

时间:2017-04-20 16:52:16

标签: xamarin.forms

我正在使用Xamarin.Forms制作一个MP3播放器,其中滑块应该显示时间已过期并允许跳转到轨道中的位置。 据我所知,只有ValueChanged事件可用,不幸的副作用是每次我的计时器更新滑块值时,我还会触发我的player.SeekTo方法,导致播放中断。

有没有办法专门在滑块上拾取触摸事件? 如果没有,有没有人对如何使这项工作有任何建议?

如果它是相关的,这是我的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();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我想我找到了一个解决方法。由于valuechanged事件包含旧值和新值,因此如果差值为负或大于2,我只会触发SeekTo。