Custom Progress bar in Xamarin Forms iOS
Hi Friends ,
Today I would like to create a custom progress bar as below .
Create a project as Xamarin forms .
CustomProgressBar and three bindable property
public static readonly BindableProperty ProgressValueProperty =
BindableProperty.Create<CustomProgressBar, double>
(p => p.ProgressValue, double.NaN, BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
var control = (CustomProgressBar)bindable;
control.ProgressValue = newValue;
});
public static readonly BindableProperty ProgressColorProperty =
BindableProperty.Create("ProgressColor", typeof(Color), typeof(CustomProgressBar), Color.Red, BindingMode.TwoWay, null, null);
public Color ProgressColor
{
get { return (Color)GetValue(ProgressColorProperty); }
set { SetValue(ProgressColorProperty, value); }
}
public static readonly BindableProperty BackColorProperty =
BindableProperty.Create("BackColor", typeof(Color), typeof(CustomProgressBar), Color.Blue, BindingMode.TwoWay, null, null);
public event EventHandler ValueChanged;
public void NotifyValueChanged()
{
if (ValueChanged != null)
{
ValueChanged(this, new EventArgs());
}
}
public class CustomProgressBar : View
{
public CustomProgressBar()
{
}
public static readonly BindableProperty ProgressValueProperty =
BindableProperty.Create<CustomProgressBar, double>
(p => p.ProgressValue, double.NaN, BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
var control = (CustomProgressBar)bindable;
control.ProgressValue = newValue;
});
public double ProgressValue
{
get { return (double)GetValue(ProgressValueProperty); }
set { SetValue(ProgressValueProperty, value); }
}
public static readonly BindableProperty ProgressColorProperty =
BindableProperty.Create("ProgressColor", typeof(Color), typeof(CustomProgressBar), Color.Red, BindingMode.TwoWay, null, null);
public Color ProgressColor
{
get { return (Color)GetValue(ProgressColorProperty); }
set { SetValue(ProgressColorProperty, value); }
}
public static readonly BindableProperty BackColorProperty =
BindableProperty.Create("BackColor", typeof(Color), typeof(CustomProgressBar), Color.Blue, BindingMode.TwoWay, null, null);
public Color BackColor
{
get { return (Color)GetValue(BackColorProperty); }
set { SetValue(BackColorProperty, value); }
}
public event EventHandler ValueChanged;
public void NotifyValueChanged()
{
if (ValueChanged != null)
{
ValueChanged(this, new EventArgs());
}
}
}
2. Custom Renderer.
Now we have create Custom Renderer for iOS .
Declare variable
private UIView _background, _range;
private UIImageView _tintImage;
Define Variable in constructor
public CustomProgressBarRenderer()
{
// Add Background Layer
_background = new UIView();
// Add Range Layer
_range = new UIView();
// Range Image Indicator
// _tintImage = new UIImageView();
_tintImage = new UIImageView();
_tintImage.Image = UIImage.FromBundle("progress");
AddSubview(_background);
AddSubview(_range);
AddSubview(_tintImage);
}
Set controls position
private bool _layouted;
public override void LayoutSubviews()
{
base.LayoutSubviews();
if (!_layouted)
{
_background.Frame = new RectangleF(0, 19, (float)Frame.Width, 2);
_background.Layer.CornerRadius = 2f;
_range.Frame = new RectangleF(0, 19, 20, 2);
_tintImage.Frame = new RectangleF(0, 1, 35, 39);
_layouted = true;
}
}
Implement control's Renderer
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Renderer")
{
// Range Guidelines Colors
_background.BackgroundColor = Element.ProgressColor.ToUIColor();
// Range Guidelines Colors
_range.BackgroundColor =Element.BackColor.ToUIColor(); //UIColor.FromRGB(0, 153, 255);
}
if (e.PropertyName == "ProgressValue")
{
if ((float)Element.ProgressValue <= .97)
{
// Set Current Posstion of Image
var progressBarWidth = (float)Frame.Width;
float posstionPrgressIndicator = progressBarWidth * (float)Element.ProgressValue;
_range.Frame = new RectangleF(0, 19, posstionPrgressIndicator, 2);
_tintImage.Frame = new RectangleF(posstionPrgressIndicator, 1, 35, 39);
}
}
}
Complete class as below
[assembly: ExportRenderer(typeof(CustomProgressBar), typeof(CustomProgressBarRenderer))]
namespace MyProgressBar.iOS.Renderer
{
public class CustomProgressBarRenderer : ViewRenderer<CustomProgressBar, CustomProgressBarRenderer>
{
private UIView _background, _range;
private UIImageView _tintImage;
public CustomProgressBarRenderer()
{
// Add Background Layer
_background = new UIView();
// Add Range Layer
_range = new UIView();
// Range Image Indicator
// _tintImage = new UIImageView();
_tintImage = new UIImageView();
_tintImage.Image = UIImage.FromBundle("progress");
AddSubview(_background);
AddSubview(_range);
AddSubview(_tintImage);
}
private bool _layouted;
public override void LayoutSubviews()
{
base.LayoutSubviews();
if (!_layouted)
{
_background.Frame = new RectangleF(0, 19, (float)Frame.Width, 2);
_background.Layer.CornerRadius = 2f;
_range.Frame = new RectangleF(0, 19, 20, 2);
_tintImage.Frame = new RectangleF(0, 1, 35, 39);
_layouted = true;
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Renderer")
{
// Range Guidelines Colors
_background.BackgroundColor = Element.ProgressColor.ToUIColor();
// Range Guidelines Colors
_range.BackgroundColor =Element.BackColor.ToUIColor(); //UIColor.FromRGB(0, 153, 255);
}
if (e.PropertyName == "ProgressValue")
{
if ((float)Element.ProgressValue <= .97)
{
// Set Current Posstion of Image
var progressBarWidth = (float)Frame.Width;
float posstionPrgressIndicator = progressBarWidth * (float)Element.ProgressValue;
_range.Frame = new RectangleF(0, 19, posstionPrgressIndicator, 2);
_tintImage.Frame = new RectangleF(posstionPrgressIndicator, 1, 35, 39);
}
}
}
}
}
3. Implement control
Xaml Page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyProgressBar" x:Class="MyProgressBar.MyProgressBarPage">
<ContentPage.Content>
<StackLayout Margin="10" Spacing="20" Padding="20">
<Button Text="Start" VerticalOptions="Center" HorizontalOptions="Center" Clicked="Handle_Clicked" />
<local:CustomProgressBar BackColor="Blue" ProgressColor="Purple" x:Name="progressBar" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Code behind
We are implement a sample progress bar
void Handle_Clicked(object sender, System.EventArgs e)
{
progressBar.ProgressValue = 0;
Xamarin.Forms.Device.StartTimer(TimeSpan.FromSeconds(.2), OnTimer);
}
private bool OnTimer()
{
progressBar.ProgressValue = progressBar.ProgressValue + .02;
return true;
}
.
You can find source code as below url
https://github.com/rahultripa/Customprogressbar
Today I would like to create a custom progress bar as below .
Create a project as Xamarin forms .
1. Create a class name
CustomProgressBar and three bindable property
ProgressValueProperty (For Indication Progress)
public static readonly BindableProperty ProgressValueProperty =
BindableProperty.Create<CustomProgressBar, double>
(p => p.ProgressValue, double.NaN, BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
var control = (CustomProgressBar)bindable;
control.ProgressValue = newValue;
});
ProgressColorProperty ( For Progress Range color )
public static readonly BindableProperty ProgressColorProperty =
BindableProperty.Create("ProgressColor", typeof(Color), typeof(CustomProgressBar), Color.Red, BindingMode.TwoWay, null, null);
public Color ProgressColor
{
get { return (Color)GetValue(ProgressColorProperty); }
set { SetValue(ProgressColorProperty, value); }
}
BackColorProperty ( Background color of Progress bar)
public static readonly BindableProperty BackColorProperty =
BindableProperty.Create("BackColor", typeof(Color), typeof(CustomProgressBar), Color.Blue, BindingMode.TwoWay, null, null);
public Color BackColor
{
get { return (Color)GetValue(BackColorProperty); }
set { SetValue(BackColorProperty, value); }
}
An event
public event EventHandler ValueChanged;
public void NotifyValueChanged()
{
if (ValueChanged != null)
{
ValueChanged(this, new EventArgs());
}
}
Whole Class
public class CustomProgressBar : View
{
public CustomProgressBar()
{
}
public static readonly BindableProperty ProgressValueProperty =
BindableProperty.Create<CustomProgressBar, double>
(p => p.ProgressValue, double.NaN, BindingMode.TwoWay, propertyChanged: (bindable, oldValue, newValue) =>
{
var control = (CustomProgressBar)bindable;
control.ProgressValue = newValue;
});
public double ProgressValue
{
get { return (double)GetValue(ProgressValueProperty); }
set { SetValue(ProgressValueProperty, value); }
}
public static readonly BindableProperty ProgressColorProperty =
BindableProperty.Create("ProgressColor", typeof(Color), typeof(CustomProgressBar), Color.Red, BindingMode.TwoWay, null, null);
public Color ProgressColor
{
get { return (Color)GetValue(ProgressColorProperty); }
set { SetValue(ProgressColorProperty, value); }
}
public static readonly BindableProperty BackColorProperty =
BindableProperty.Create("BackColor", typeof(Color), typeof(CustomProgressBar), Color.Blue, BindingMode.TwoWay, null, null);
public Color BackColor
{
get { return (Color)GetValue(BackColorProperty); }
set { SetValue(BackColorProperty, value); }
}
public event EventHandler ValueChanged;
public void NotifyValueChanged()
{
if (ValueChanged != null)
{
ValueChanged(this, new EventArgs());
}
}
}
2. Custom Renderer.
Now we have create Custom Renderer for iOS .
Declare variable
private UIView _background, _range;
private UIImageView _tintImage;
Define Variable in constructor
public CustomProgressBarRenderer()
{
// Add Background Layer
_background = new UIView();
// Add Range Layer
_range = new UIView();
// Range Image Indicator
// _tintImage = new UIImageView();
_tintImage = new UIImageView();
_tintImage.Image = UIImage.FromBundle("progress");
AddSubview(_background);
AddSubview(_range);
AddSubview(_tintImage);
}
Set controls position
private bool _layouted;
public override void LayoutSubviews()
{
base.LayoutSubviews();
if (!_layouted)
{
_background.Frame = new RectangleF(0, 19, (float)Frame.Width, 2);
_background.Layer.CornerRadius = 2f;
_range.Frame = new RectangleF(0, 19, 20, 2);
_tintImage.Frame = new RectangleF(0, 1, 35, 39);
_layouted = true;
}
}
Implement control's Renderer
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Renderer")
{
// Range Guidelines Colors
_background.BackgroundColor = Element.ProgressColor.ToUIColor();
// Range Guidelines Colors
_range.BackgroundColor =Element.BackColor.ToUIColor(); //UIColor.FromRGB(0, 153, 255);
}
if (e.PropertyName == "ProgressValue")
{
if ((float)Element.ProgressValue <= .97)
{
// Set Current Posstion of Image
var progressBarWidth = (float)Frame.Width;
float posstionPrgressIndicator = progressBarWidth * (float)Element.ProgressValue;
_range.Frame = new RectangleF(0, 19, posstionPrgressIndicator, 2);
_tintImage.Frame = new RectangleF(posstionPrgressIndicator, 1, 35, 39);
}
}
}
Complete class as below
[assembly: ExportRenderer(typeof(CustomProgressBar), typeof(CustomProgressBarRenderer))]
namespace MyProgressBar.iOS.Renderer
{
public class CustomProgressBarRenderer : ViewRenderer<CustomProgressBar, CustomProgressBarRenderer>
{
private UIView _background, _range;
private UIImageView _tintImage;
public CustomProgressBarRenderer()
{
// Add Background Layer
_background = new UIView();
// Add Range Layer
_range = new UIView();
// Range Image Indicator
// _tintImage = new UIImageView();
_tintImage = new UIImageView();
_tintImage.Image = UIImage.FromBundle("progress");
AddSubview(_background);
AddSubview(_range);
AddSubview(_tintImage);
}
private bool _layouted;
public override void LayoutSubviews()
{
base.LayoutSubviews();
if (!_layouted)
{
_background.Frame = new RectangleF(0, 19, (float)Frame.Width, 2);
_background.Layer.CornerRadius = 2f;
_range.Frame = new RectangleF(0, 19, 20, 2);
_tintImage.Frame = new RectangleF(0, 1, 35, 39);
_layouted = true;
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Renderer")
{
// Range Guidelines Colors
_background.BackgroundColor = Element.ProgressColor.ToUIColor();
// Range Guidelines Colors
_range.BackgroundColor =Element.BackColor.ToUIColor(); //UIColor.FromRGB(0, 153, 255);
}
if (e.PropertyName == "ProgressValue")
{
if ((float)Element.ProgressValue <= .97)
{
// Set Current Posstion of Image
var progressBarWidth = (float)Frame.Width;
float posstionPrgressIndicator = progressBarWidth * (float)Element.ProgressValue;
_range.Frame = new RectangleF(0, 19, posstionPrgressIndicator, 2);
_tintImage.Frame = new RectangleF(posstionPrgressIndicator, 1, 35, 39);
}
}
}
}
}
3. Implement control
Xaml Page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyProgressBar" x:Class="MyProgressBar.MyProgressBarPage">
<ContentPage.Content>
<StackLayout Margin="10" Spacing="20" Padding="20">
<Button Text="Start" VerticalOptions="Center" HorizontalOptions="Center" Clicked="Handle_Clicked" />
<local:CustomProgressBar BackColor="Blue" ProgressColor="Purple" x:Name="progressBar" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Code behind
We are implement a sample progress bar
void Handle_Clicked(object sender, System.EventArgs e)
{
progressBar.ProgressValue = 0;
Xamarin.Forms.Device.StartTimer(TimeSpan.FromSeconds(.2), OnTimer);
}
private bool OnTimer()
{
progressBar.ProgressValue = progressBar.ProgressValue + .02;
return true;
}
.
You can find source code as below url
https://github.com/rahultripa/Customprogressbar
do u have for android?
ReplyDelete