how to change player icon in xamarin forms - xamarin.forms

Please i need some one to help me on how to change player icon into my player page in xamarin forms
This is my code:
PlayerPage.xaml
<StackLayout>
<Button x:Name="btnpause"
WidthRequest="20"
HeightRequest="20"
HorizontalOptions="Center"
ImageSource="pause.png" />
<Button x:Name="btnPlay"
WidthRequest="20"
HeightRequest="20"
HorizontalOptions="Center"
ImageSource="play.png" />
<Switch x:Name="switchLoop" IsToggled="False" />
</StackLayout>
PlayerPage.xaml.cs
ISimpleAudioPlayer player;
public PlayerPage()
{
InitializeComponent();
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load("music.mp3");
btnPlay.Clicked += BtnPlayClicked;
switchLoop.Toggled += SwitchLoopToggled;
}
private void SwitchLoopToggled(object sender, ToggledEventArgs e)
{
Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Loop = switchLoop.IsToggled;
}
private void BtnPlayClicked(object sender, EventArgs e)
{
Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Play();
}
Thank you.

Take a look at PlaybackEnded , it is raised when audio playback completes successfully .
You can control the button's visibility in the event .
Code example
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.PlaybackEnded += (sender,e)=>
{
btnPlay.IsVisible = true;
btnpause.IsVisible = false;
};

I think you mean like this ,did not added the image .Use a ImageButton instead.
On start the button play and the loop switch , when the switch is True the sounds repeats it self. When start the pause button is showing push it the Play is showing again to resume. The example project is on Github https://github.com/borisoprit/MusicStackOverflow
<StackLayout>
<ImageButton
x:Name="btnPlay"
HeightRequest="50"
HorizontalOptions="Center"
Source="Play.png"
VerticalOptions="Center"
WidthRequest="50" />
<ImageButton
x:Name="btnPause"
HeightRequest="50"
HorizontalOptions="Center"
Source="pause.png"
VerticalOptions="Center"
WidthRequest="50"
IsVisible="false"/>
<Label
HorizontalOptions="Start"
Text="Loop:"
VerticalOptions="Center" />
<Switch
x:Name="switchLoop"
HorizontalOptions="Start"
IsToggled="False"
VerticalOptions="Center" />
</StackLayout>
PlayerPage.xaml.cs i also place the OnAppearing. This is the state of the btnpause Isvisible = false .Music ended the Play button is there and pause is hiding again.
public HeadProjectAudioPage()
{
InitializeComponent();
btnPause.IsVisible = false;
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.PlaybackEnded += (sender, e) =>
{
btnPlay.IsVisible = true;
btnPause.IsVisible = false;
};
player.Load("running.mp3");
btnPlay.Clicked += BtnPlayClicked;
btnPause.Clicked += BtnPauseClicked;
switchLoop.Toggled += SwitchLoopToggled;
}
protected override void OnAppearing()
{
base.OnAppearing();
btnPause.IsVisible = false;
}
private void SwitchLoopToggled(object sender, ToggledEventArgs e)
{
Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Loop = switchLoop.IsToggled;
}
private void BtnPlayClicked(object sender, EventArgs e)
{
btnPause.IsVisible = true;
btnPlay.IsVisible = false;
Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Play();
}
private void BtnPauseClicked(object sender, EventArgs e)
{
btnPlay.IsVisible = true;
btnPause.IsVisible = false;
Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current.Pause();
}
}

Related

How to disable CTRL keyboard in WPF DataGrid

I have a datagrid where in i want to prevent user from CTRL Key press.
<ImageBrush ImageSource="/AB17035_ZLT_Client;component/Images/bum_big.PNG"
Stretch="Uniform" Opacity="0.05" />
</Border.Background>
<DataGrid Name="PlanGrid" HorizontalAlignment="Stretch" FontSize="16" RowHeight="30" HorizontalScrollBarVisibility="Visible"
VerticalAlignment="Stretch"
AutoGenerateColumns="True"
SelectionMode="Extended"
VerticalGridLinesBrush="Transparent"
Background="Transparent" RowBackground="Transparent"
ItemsSource="{Binding PlanDataView, Mode=TwoWay}"
IsReadOnly="True" SelectionUnit="FullRow" IsSynchronizedWithCurrentItem="True" Cursor="Arrow" AllowDrop="True">
<DataGrid.InputBindings>
<KeyBinding Gesture="Ctrl" Command="ApplicationCommands.NotACommand"></KeyBinding>
</DataGrid.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<ei:CallMethodAction MethodName="PlanGrid_Loaded" TargetObject="{Binding}"></ei:CallMethodAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
If user tries for CTLR key press it should not work on wpf datagrid.
I googled and found the answer for it. Below is the piece of code to prevent from ctrl key press.
private void PreviewKeyDown(object sender, KeyEventArgs e)
{
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
e.Handled = true;
MessageBox.Show("CTRL Key is not allowed");
}
}
also add this function "PreviewKeyDown" to load event of data grid as below:
public void PlanGrid_Loaded(object sender, RoutedEventArgs e)
{
planDatagrid.KeyDown += new KeyEventHandler(PreviewKeyDown);
}
Code Behind
InitializeComponent();
dvSalesEntryDataGrid.PreviewKeyDown += Datagrid_PreviewKeyDown;
and Methods
private void Datagrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.RightCtrl||e.Key==Key.LeftCtrl)
{
e.Handled = true;
}
}

When I am navigating to a new Xamarin Page, content isnt displaying when I am running System.Timer.Timer code

I used the System.Timers.Timer(); code to do the count down Timer on page load and then I used the Navigate.Push to go into another page.
Timer Code on page load:
public Index()
{
InitializeComponent();
StartCountDownTimer();
}
DateTime endTime = new DateTime(2019, 08, 25, 14, 00, 0);
public void StartCountDownTimer()
{
try
{
timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += t_Tick;
TimeSpan ts = endTime - DateTime.Now;
lblCountDown.Text = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds'");
timer.Start();
}
catch (Exception ex)
{
string Error = ex.Message;
}
}
System.Timers.Timer timer;
void t_Tick(object sender, EventArgs e)
{
try
{
TimeSpan ts = endTime - DateTime.Now;
string NewTimer = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds'");
//txtCountDown.Text = NewTimer;
lblCountDown.Text = NewTimer;
if ((ts.TotalMilliseconds < 0) || (ts.TotalMilliseconds < 1000))
{
timer.Stop();
lblCountDown.Text = "The day has arrived";
}
}
catch (Exception ex)
{
string Error = ex.Message;
}
}
Navigate Code using a button click on the same page:
private void ClickAboutTab(object sender, EventArgs e)
{
await Navigation.PushAsync(new ReferralPage());
}
Code of page I am navigating to:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:behavior="clr-namespace:AppName.Validation"
xmlns:views="clr-namespace:AppName"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
xmlns:input="clr-namespace:Plugin.InputKit.Shared.Controls;assembly=Plugin.InputKit"
x:Class="AppName.Pages.ReferralPage"
Title="Referral">
<ContentPage.Content>
<ScrollView>
<AbsoluteLayout>
<StackLayout AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All" HorizontalOptions="CenterAndExpand">
<StackLayout>
<Grid BackgroundColor="White">
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" Margin="0,10,0,0">
<controls:CircleImage Source="Assets/xinix.png" WidthRequest="160" HeightRequest="160" ></controls:CircleImage>
</StackLayout>
<Grid Grid.Row="1" Margin="20,0,20,0">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Entry Placeholder="First Name" x:Name="txtFirstname" Grid.Row="0"/>
<Entry x:Name="txtLastname" Placeholder="Last Name" Grid.Row="1"/>
<Entry x:Name="txtEmail" Placeholder="name#domain.com" Grid.Row="2"/>
<Entry x:Name="txtPhone" Placeholder="Cell Phone" Grid.Row="3" MaxLength="10" Keyboard="Telephone"/>
<Button Text="Submit" x:Name="btnSubmit" Clicked="btnReferral_clicked" BackgroundColor="#3897F0" TextColor="White" HeightRequest="50" VerticalOptions="Start" Grid.Row="4"/>
</Grid>
</Grid>
</StackLayout>
</StackLayout>
<views:MenuBar AbsoluteLayout.LayoutBounds="0,1,1,52"
AbsoluteLayout.LayoutFlags="PositionProportional,WidthProportional"/>
</AbsoluteLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
public ReferralPage()
{
InitializeComponent();
}
Solutions I already tried before navigating are:
timer.Stop();
timer.Dispose();
timer = null;
Device.BeginInvokeOnMainThread(async () =>);
updates to UI elements need to happen on the UI thread
Device.BeginInvokeOnMainThread( () => {
lblCountDown.Text = NewTimer;
});
I have updated my code. The Device.BeginInvokeOnMainThread you tried before, could solve your problem. Maybe you try the wrong way. You could refer to the code below.
void t_Tick(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
try
{
TimeSpan ts = endTime - DateTime.Now;
string NewTimer = ts.ToString("d' Days 'h' Hours 'm' Minutes 's' Seconds'");
lblCountDown.Text = NewTimer;
if ((ts.TotalMilliseconds < 0) || (ts.TotalMilliseconds < 1000))
{
timer.Stop();
lblCountDown.Text = "The day has arrived";
}
}
catch (Exception ex)
{
string Error = ex.Message;
}
});
}
My result:

Flexlayout does not work with command and command parameter

I am being trying to use the flexlayout and it's great but now for each item in the stack layout i need to add tapped gesturer,command etc..
Whatever I try does not work.The only thing that works is the stacklayout.TapGestureRecognizer but as soon as I try to use the command does not work.
I even tried the https://taubensee.net/adding-touch-events-to-flexlayouts/
and added a commandparameter bindable property but does not work either.
How do you add a command with commandparameter to flexlayout .below is my code
<FlexLayout BindableLayout.ItemsSource="{Binding Customers}"
AlignContent="Start"
AlignItems="Start"
Direction="Row"
JustifyContent="Start"
Wrap="Wrap">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout
FlexLayout.AlignSelf="Start"
FlexLayout.Basis="50%">
<!--<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
</StackLayout.GestureRecognizers>-->
<Frame>
<!--<Frame.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ItemTappedCommand}"
CommandParameter="{Binding .}" />
</Frame.GestureRecognizers>-->
<StackLayout>
<Label Text="whatever"></Label>
<!--<Image Source="myimage.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ItemTappedCommand}" CommandParameter="AAAA"
NumberOfTapsRequired="1"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>-->
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
<!--<FlexLayout.Behaviors>
<behaviors:FlexLayoutItemTappedBehavior
Command="{Binding ItemTappedCommand2}" CommandParameter="{Binding .}"/>
</FlexLayout.Behaviors>-->
</FlexLayout>
FlexLayout maybe miss the touch events and commands , have a try with Behavior to realize it.
Create a new class that inherits from Behavior<T>:
public class FlexLayoutItemTappedBehavior : Behavior<FlexLayout>
{
public static readonly BindableProperty CommandProperty =
BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(FlexLayoutItemTappedBehavior), defaultBindingMode: BindingMode.OneWay);
public static readonly BindableProperty ParamaterProperty =
BindableProperty.Create(nameof(Paramater), typeof(object), typeof(FlexLayoutItemTappedBehavior), defaultBindingMode: BindingMode.OneWay);
public ICommand Command
{
get => (ICommand)this.GetValue(CommandProperty);
set => this.SetValue(CommandProperty, value);
}
public object Paramater
{
get => (object)this.GetValue(ParamaterProperty);
set => this.SetValue(ParamaterProperty, value);
}
protected override void OnAttachedTo(FlexLayout bindable)
{
base.OnAttachedTo(bindable);
if (bindable.BindingContext != null)
{
this.BindingContext = bindable.BindingContext;
}
bindable.BindingContextChanged += this.OnFlexLayoutBindingChanged;
bindable.ChildAdded += this.OnFlexLayoutChildAdded;
}
protected override void OnDetachingFrom(FlexLayout bindable)
{
base.OnDetachingFrom(bindable);
bindable.BindingContextChanged -= this.OnFlexLayoutBindingChanged;
bindable.ChildAdded -= this.OnFlexLayoutChildAdded;
foreach (var child in bindable.Children)
{
if (child is View childView && childView.GestureRecognizers.Any())
{
var tappedGestureRecognizers = childView.GestureRecognizers.Where(x => x is TapGestureRecognizer).Cast<TapGestureRecognizer>();
foreach (var tapGestureRecognizer in tappedGestureRecognizers)
{
tapGestureRecognizer.Tapped -= this.OnItemTapped;
childView.GestureRecognizers.Remove(tapGestureRecognizer);
}
}
}
}
private void OnFlexLayoutBindingChanged(object sender, EventArgs e)
{
if (sender is FlexLayout flexLayout)
{
this.BindingContext = flexLayout.BindingContext;
}
}
private void OnFlexLayoutChildAdded(object sender, ElementEventArgs args)
{
if (args.Element is View view)
{
var tappedGestureRecognizer = new TapGestureRecognizer();
tappedGestureRecognizer.Tapped += this.OnItemTapped;
view.GestureRecognizers.Add(tappedGestureRecognizer);
}
}
private async void OnItemTapped(object sender, EventArgs e)
{
if (sender is VisualElement visualElement)
{
var animations = new List<AnimationBase>();
var scaleIn = new ScaleToAnimation
{
Target = visualElement,
Scale = .95,
Duration = "50"
};
animations.Add(scaleIn);
var scaleOut = new ScaleToAnimation
{
Target = visualElement,
Scale = 1,
Duration = "50"
};
animations.Add(scaleOut);
var storyBoard = new StoryBoard(animations);
await storyBoard.Begin();
}
if (sender is BindableObject bindable && this.Command != null && this.Command.CanExecute(null))
{
object resolvedParameter;
if (Paramater != null)
{
resolvedParameter = Paramater;
}
else
{
resolvedParameter = e;
}
if (Command.CanExecute(resolvedParameter))
{
this.Command.Execute(bindable.BindingContext);
}
}
}
}
Lastly, in order to use this Behavior from XAML, you can reference it like this:
<FlexLayout.Behaviors>
<behaviors:FlexLayoutItemTappedBehavior
Command="{Binding NavigateToDetailCommand}" Paramater="{Binding .}"/>
</FlexLayout.Behaviors>
About Reusable EventToCommandBehavior , you can refer to here .

How to change the Text color of placeholder in Xamarin forms

Is it possible to change the Text color of part of the placeholder.
<Controls:BorderlessEntry Grid.Row="1" Grid.Column="0"
x:Name="ABS_ID"
Placeholder="Enter Name Here *"/>
I want to change the asterisk "*" Color to red and rest of the text will have default color.
Any help is appreciated!
You can try the following workaround:
Wrap an Entry and a Label into a StackLayout. And make the StackLayout like an Entry with placeholder.
The code is like this:
MainPage.xaml:
<StackLayout Orientation="Horizontal" HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<Entry x:Name="ABS_ID"
Text="Enter Name Here "
HorizontalOptions="Start"
Focused="OnEntryFocused"
Unfocused="OnEntryUnFocused"/>
<Label x:Name="ABS_ID2"
Text="*"
TextColor="Red"
HorizontalOptions="StartAndExpand"
VerticalTextAlignment="Center"
Margin="-20"/>
</StackLayout>
MainPage.xaml.cs:
public partial class MainPage : ContentPage
{
bool showPlaceHolder = true;
public MainPage()
{
InitializeComponent();
}
void OnEntryFocused(object sender, EventArgs e)
{
if (showPlaceHolder) {
ABS_ID.Text = "";
ABS_ID2.Text = "";
}
}
void OnEntryUnFocused(object sender, EventArgs e)
{
if ((ABS_ID.Text == "") && (ABS_ID2.Text == ""))
{
ABS_ID.Text = "Enter Name Here ";
ABS_ID2.Text = "*";
showPlaceHolder = true;
}
else {
showPlaceHolder = false;
}
}
}
And the result is:

Display lyrics while playing song in xamarin forms

I made audio player in xamarin forms(PCL) as Follows:
Audio.xaml(PCL):
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CPL.pages.audio">
<ContentPage.Content>
<StackLayout>
<ListView x:Name="lstSongsList" ItemSelected="lstSongsList_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label x:Name="lblFileName" Text="{Binding Name}"></Label>
<Label x:Name="lblLength" Text="{Binding Length}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Audio.xaml.cs(PCL):
private void lstSongsList_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var selected = (Entity.File)e.SelectedItem;
try
{
if(selected != null)
{
Navigation.PushAsync(new player(selected));
}
}
catch(Exception ex)
{
}
}
Player.xaml.cs(PCL):
public player(Entity.File entity)
{
InitializeComponent();
_file = entity;
DependencyService.Get<iFile>().PlayFile(entity.FullPath);
}
Files.cs(Android):
public bool PlayFile(string filePath)
{
if(currentFile != filePath)
{
if (_mediaPlayer != null)
{
_mediaPlayer.Stop();
}
_mediaPlayer = MediaPlayer.Create(global::Android.App.Application.Context, Android.Net.Uri.Parse(filePath));
_mediaPlayer.Start();
var file = rootDirectory.GetFiles(".lrc", SearchOption.AllDirectories).FirstOrDefault();
_mediaPlayer.AddTimedTextSource(file.FullName, "application/octet-stream");
_mediaPlayer.SetVolume(100, 100);
currentFile = filePath;
}
return true;
}
It works fine in play and pause but I am unable to display lyrics which is attached in addtimedTextSource file. I have to display lyrics while play the song.
Anyone have idea about displaying lyrics of audio in xamarin forms?

Resources