Xamarin音频播放器进度条不一致

时间:2017-07-03 18:40:37

标签: visual-studio-2015 xamarin.android xamarin.forms

我在Xamarin Android中遇到了进度条的问题。我使用以下代码播放特定的音频文件。

await CrossMediaManager.Current.Play(await DependencyService.Get<IMedia>().GetPath(answer.ResourceURL));

,进度条代码如下:

CrossMediaManager.Current.PlayingChanged += (sender, ev) =>
                            {
                                progressBar.Progress = ev.Position.TotalSeconds / ev.Duration.TotalSeconds;
                                elapseTime.Text = Math.Abs(ev.Position.TotalMinutes).ToString("0.00");
                                totalTime.Text = Math.Abs((ev.Duration.TotalMinutes) - ev.Position.TotalMinutes).ToString("0.00");
                            };

我在播放后放置了此进度条形码。 所以现在我的问题是,在我的屏幕上有一些音频文件,例如5个带有5个播放按钮。 如果我点击第二个文件,音频播放完美。但是第5个文件的进度条也被移动但音频没有播放。仅移动进度条。 请找到附件图片。Screenshot for progress bar

如果我将进度条代码放在我的构造函数中,则会移动所有文件的所有进度条,但只播放一个文件。

有人请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

  

我正在使用卡片组件,它将根据我的ViewModel中数据库中的文件数进行迭代。文件的数量是动态的。

我不确定您使用的是哪个控件,但根据您的描述,您可能正在使用ListViewRecyclerView或类似的内容,其项目可以自动插入列表使用Adapter

然后,对于这样的控件,不建议使用其名称来检索项目中控件的实例,因为每个项目都有一个具有相同名称的控件,尤其是您正在使用Xamarin.Forms对于开发,如果您在PCL中使用ListView而在DataTemplate中使用ItemTemplate,则它就像是每个项目的结构。

假设你在PCL中使用ListView,而不是在Android平台上,那么你可以使用这样的代码。

首先创建Image的子类,以便我们为每个项目提供ID,例如:

public class MyImage : Image
{
    public int ItemID
    {
        get { return (int)GetValue(ItemIDProperty); }
        set { SetValue(ItemIDProperty, value); }
    }

    public static readonly BindableProperty ItemIDProperty = BindableProperty.Create<MyImage, int>(p => p.ItemID, default(int));
}

然后在XAML中使用例如:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YOURNAMESPACE"
             x:Class="YOURNAMESPACE.MainPage">
    <ContentPage.Content>

            <ListView x:Name="lv">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal" HorizontalOptions="Fill">
                                <local:MyImage x:Name="xplay" Source="play_circle.png" ItemID="{Binding id}">
                                    <Image.GestureRecognizers>
                                        <TapGestureRecognizer Tapped="TrackEntity3" NumberOfTapsRequired="1" />
                                    </Image.GestureRecognizers>
                                </local:MyImage>
                                <StackLayout HorizontalOptions="FillAndExpand" Orientation="Vertical">
                                    <StackLayout Orientation="Horizontal">
                                        <Label x:Name="elapseTime" HorizontalOptions="Start" HorizontalTextAlignment="Start" Text="{Binding elapsetime,Mode=OneWay}"></Label>
                                        <Label x:Name="totalTime" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" Text="{Binding totaltime,Mode=OneWay}"></Label>
                                    </StackLayout>
                                    <ProgressBar x:Name="progressBar" WidthRequest="300"  Progress="{Binding progress,Mode=OneWay}" />
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

    </ContentPage.Content>
</ContentPage>

创建数据模型:

public class MyMedia : INotifyPropertyChanged
{
    public int id { get; set; }

    private string _elapsetime;

    public string elapsetime
    {
        get { return _elapsetime; }
        set
        {
            if (value != _elapsetime)
            {
                _elapsetime = value;
                OnPropertyChanged();
            }
        }
    }

    private string _totaltime;

    public string totaltime
    {
        get { return _totaltime; }
        set
        {
            if (value != _totaltime)
            {
                _totaltime = value;
                OnPropertyChanged();
            }
        }
    }

    private double _progress;

    public double progress
    {
        get { return _progress; }
        set
        {
            if (value != _progress)
            {
                _progress = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

TrackEntity3事件中:

private MyMedia currentItem;

private void TrackEntity3(object sender, EventArgs e)
{
    var image = sender as MyImage;
    var id = image.ItemID;
    foreach (var source in lv.ItemsSource)
    {
        var item = source as MyMedia;
        if (item.id == id)
        {
            //play music here
            //find labels and progressbar
            if (currentItem != null)
            {
                currentItem.progress = 0;
                currentItem.totaltime = "";
                currentItem.elapsetime = "";
            }
            currentItem = item;
        }
    }
}

CrossMediaManager.Current.PlayingChanged事件中直接更改此项目:

CrossMediaManager.Current.PlayingChanged += (sender, ev) =>
                            {
                                currentItem.progress = ...;
                                currentItem.elapsetime = ...;
                                currentItem.totaltime = ...;

                            };

由于它是ListView,您可以使用ObservableCollection添加项目:

private ObservableCollection<MyMedia> collection = new ObservableCollection<MyMedia>();

public MainPage()
{
    InitializeComponent();
    for (int i = 0; i < 5; i++)
    {
        collection.Add(new MyMedia { id = i });
    }
    lv.ItemsSource = collection;
}

听起来你正在使用MVVM模式,你可以将代码移到你的viewmodel中。如果您使用其他控件动态添加项目,则可以发表评论。