我在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
如果我将进度条代码放在我的构造函数中,则会移动所有文件的所有进度条,但只播放一个文件。
有人请帮我解决这个问题。
答案 0 :(得分:0)
我正在使用卡片组件,它将根据我的ViewModel中数据库中的文件数进行迭代。文件的数量是动态的。
我不确定您使用的是哪个控件,但根据您的描述,您可能正在使用ListView
或RecyclerView
或类似的内容,其项目可以自动插入列表使用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中。如果您使用其他控件动态添加项目,则可以发表评论。