【问题标题】:Xamarin.forms slider as an Audio player barXamarin.forms 滑块作为音频播放器栏
【发布时间】:2016-05-17 09:21:52
【问题描述】:

我想使用 xamarin.forms 的滑块控件作为音频播放器栏。我有一个依赖服务来播放录音并获取总持续时间和当前位置。如何将它设置到我的滑块?

她是我的代码:

Button btnPlay = new Button
{
    Text = "Play/Pause",
    Command = new Command(() =>
                    {
                        DependencyService.Get<IAudio>().PlayMp3File();
                    })
};
Button btnStop = new Button { Text = "Stop" };
TimeSpan timeSpan = DependencyService.Get<IAudio>().GetInfo();
Label lblDuration = new Label { Text = String.Format("{0:hh\\:mm\\:ss}", timeSpan) };

var slider = new Slider {
    Minimum = 0,
    Maximum = timeSpan.TotalHours,
};
var label = new Label {
    Text = "Slider value is 0",
    FontSize = 25,
    HorizontalOptions = LayoutOptions.Start,
};
slider.ValueChanged += 
    (sender, e) => 
    {
        label.Text = String.Format("Slider value is {0:hh\\:mm\\:ss}", TimeSpan.FromMilliseconds(e.NewValue));
        DependencyService.Get<IAudio>().SeekTo(Convert.ToInt32(e.NewValue));

    };
MainPage = new ContentPage
{
    Content = new StackLayout {
        Children = {
            btnPlay,
            btnStop,
            slider,
            lblDuration,
            label
        }
    },  
    Padding = new Thickness (10, Device.OnPlatform (20, 0, 0), 10, 5)
};

我在标签中设置总持续时间。我将如何编程更改滑块以将标签设置为当前位置。我的滑块值将如何根据播放的文件增加?

编辑

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

namespace AudioTest
{
    public interface IAudio
    {
        Task PlayMp3File();
       // bool PlayWavFile(string fileName);

        Task SeekTo(int msec);
        TimeSpan GetInfo();

        void Stop();
        double CurrentPosition();

        bool Isplaying();
    }
}

音频服务.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AudioTest.Droid;
using Xamarin.Forms;
using Android.Media;
using System.Threading.Tasks;


[assembly: Dependency(typeof(AudioService))]

namespace AudioTest.Droid
{

    public class AudioService : IAudio
    {
        public AudioService() { }

        MediaPlayer player = null;

        public async Task StartPlayerAsync()
        {
            try
            {
                if (player == null)
                {
                    player = new MediaPlayer();
                    player = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.test);
                    player.Start();
                }
                else
                {
                    if (player.IsPlaying == true)
                    {
                        player.Pause();
                    }
                    else
                    {
                        player.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.StackTrace);
            }
        }

        public void StopPlayer()
        {
            if ((player != null))
            {
                if (player.IsPlaying)
                {
                    player.Stop();
                }
                player.Release();
                player = null;
            }
        }

        public async Task PlayMp3File()
        {
            await StartPlayerAsync();
        }

        public void Stop()
        {
            this.StopPlayer();
        }

        public async Task SeekTo( int s)
        {
            await seekTo(s);
        }

        public double CurrentPosition()
        {
            if ((player != null))
            {
                return player.CurrentPosition;
            }
            else
            { return 0; }
        }

        private async Task seekTo(int mseconds)
        {
            if (player == null)
            {
                player = new MediaPlayer();
                player = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.test);

            }

            player.SeekTo(mseconds);
            player.Start();
        }



        public TimeSpan GetInfo()
        {
            int arr;
            if (player == null)
            {
                player = new MediaPlayer();
                player = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.test);

            }
            arr = player.Duration;

            return TimeSpan.FromMilliseconds(arr);
        }


       public bool Isplaying()
        {
            if (player == null)
            {
                return false;


            }
            else { 
            return player.IsPlaying;
                }

        }
    }
}

【问题讨论】:

    标签: c# xamarin.forms


    【解决方案1】:

    在我回答这个问题之前,让我问你一个问题:你真的希望滑块跟踪小时数吗?我希望媒体滑块可以跟踪几秒或十分之一秒;小时是一个非常粗略的步骤。

    假设您是IAudio 接口及其实现的作者,我的建议是让IAudio 接口公开并触发一个事件(例如:PositionChanged),只要播放位置变化。 IAudio 接口的实现超出了这个问题的范围,但我希望你订阅一个事件或使用你正在使用的任何媒体堆栈注册一个回调,这反过来会触发 @987654325 @事件。

    注意:我还假设您的意思是秒;如果您确实是指小时数,请将以下位置更改为小时数。

    public class PositionChangedEventArgs : EventArgs
    {
        public PositionChangedEventArgs(int seconds)
        {
            Seconds = seconds;
        }
    
        public int Seconds { get; set; }
    }
    
    public interface IAudio
    {
        ...
        event EventHandler<PositionChangedEventArgs> PositionChanged;
    }
    

    然后,在 PositionChanged 的​​事件处理程序中,您将更新滑块的位置:

    // note that we're caching our reference to IAudio;
    // I don't know whether it's a singleton or not
    var audioService = DependencyService.Get<IAudio>(); 
    TimeSpan timeSpan = audioService.GetInfo();
    Label lblDuration = new Label { Text = String.Format("{0:hh\\:mm\\:ss}", timeSpan) };
    
    var slider = new Slider {
        Minimum = 0,
        Maximum = timeSpan.TotalSeconds,
    };
    audioService.PositionChanged += (s, e) => {
        slider.Value = e.Position;
        label.Text = String.Format("Slider value is {0}", e.Position);
    }
    

    【讨论】:

    • 对不起,我的错。我希望滑块跟踪第二个。 :-(
    • 我已经编辑了我的问题以添加接口类结构
    • 我无法在界面上添加事件PositionChanged,得到Error 4 Expected class, delegate, enum, interface, or struct
    • 如果您收到该错误,则说明语法上有问题。您是否将该事件声明添加到接口定义的主体中?顺便说一句,请确保您不包括我的椭圆 (...) - 我只是把它放在那里表示还有其他成员!
    • 我已将其添加到 IAudio 接口类。将class 添加到public class PositionChangedEventArgs : EventArgs 后,该错误现已修复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多