Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Android Material] Linear Progress Indicator #5079

Merged
merged 1 commit into from
Feb 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Xamarin.Forms.Controls/CoreGallery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ public override string ToString()
new GalleryPageFactory(() => new OpenGLViewCoreGalleryPage(), "OpenGLView Gallery"),
new GalleryPageFactory(() => new PickerCoreGalleryPage(), "Picker Gallery"),
new GalleryPageFactory(() => new ProgressBarCoreGalleryPage(), "ProgressBar Gallery"),
new GalleryPageFactory(() => new MaterialProgressBarGallery(), "[Material] ProgressBar Gallery"),
new GalleryPageFactory(() => new ScrollGallery(), "ScrollView Gallery"),
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Horizontal), "ScrollView Gallery Horizontal"),
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Both), "ScrollView Gallery 2D"),
Expand Down
102 changes: 102 additions & 0 deletions Xamarin.Forms.Controls/GalleryPages/MaterialProgressBarGallery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
namespace Xamarin.Forms.Controls
{
public class MaterialProgressBarGallery : ContentPage
{
public MaterialProgressBarGallery()
{
Visual = VisualMarker.Material;

var progressBar = new ProgressBar();

Slider[] ColorSlider =
{
new Slider(0, 1, 0.5),
new Slider(0, 1, 0.5),
new Slider(0, 1, 0.5),
new Slider(0, 1, 0.5)
};
Slider[] BackColorSlider =
{
new Slider(0, 1, 0.5),
new Slider(0, 1, 0.5),
new Slider(0, 1, 0.5),
new Slider(0, 1, 0.5)
};

var actions = new Grid()
{
ColumnDefinitions =
{
new ColumnDefinition { Width = 10 },
new ColumnDefinition { Width = GridLength.Star },
new ColumnDefinition { Width = 30 },
new ColumnDefinition { Width = 10 },
new ColumnDefinition { Width = GridLength.Star },
new ColumnDefinition { Width = 30 },
}
};

actions.AddChild(new Label { Text = "Primary color" }, 0, 0, 3);
for (int i = 0; i < ColorSlider.Length; i++)
{
var valueLabel = new Label();
ColorSlider[i].ValueChanged += (_, e) =>
{
progressBar.ProgressColor = Color.FromRgba(ColorSlider[0].Value, ColorSlider[1].Value, ColorSlider[2].Value, ColorSlider[3].Value);
valueLabel.Text = ((int)(e.NewValue * 255)).ToString();
};
actions.AddChild(new Label { Text = GetColorLetter(i) }, 0, i + 1);
actions.AddChild(ColorSlider[i], 1, i + 1);
actions.AddChild(valueLabel, 2, i + 1);
}

actions.AddChild(new Label { Text = "Background color" }, 3, 0, 3);
for (int i = 0; i < BackColorSlider.Length; i++)
{
var valueLabel = new Label();
BackColorSlider[i].ValueChanged += (_, e) =>
{
progressBar.BackgroundColor = Color.FromRgba(BackColorSlider[0].Value, BackColorSlider[1].Value, BackColorSlider[2].Value, BackColorSlider[3].Value);
valueLabel.Text = ((int)(e.NewValue * 255)).ToString();
};
actions.AddChild(new Label { Text = GetColorLetter(i) }, 3, i + 1);
actions.AddChild(BackColorSlider[i], 4, i + 1);
actions.AddChild(valueLabel, 5, i + 1);
}

var valueSlider = new Slider(0, 1, progressBar.Progress);
valueSlider.ValueChanged += (_, e) => progressBar.Progress = e.NewValue;
actions.AddChild(new Label { Text = "Value" }, 0, 5, 6);
actions.AddChild(valueSlider, 0, 6, 6);

var heightSlider = new Slider(0, 100, 4);
heightSlider.ValueChanged += (_, e) => progressBar.HeightRequest = e.NewValue;
actions.AddChild(new Label { Text = "HeightRequest" }, 0, 7, 6);
actions.AddChild(heightSlider, 0, 8, 6);

Content = new StackLayout
{
Children =
{
actions,
progressBar
}
};
}

string GetColorLetter(int index)
{
switch (index)
{
case 0:
return "R";
case 1:
return "G";
case 2:
return "B";
default:
return "A";
}
}
}
}
2 changes: 1 addition & 1 deletion Xamarin.Forms.Material.iOS/MaterialProgressBarRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Xamarin.Forms.Platform.iOS.Material
{
public class MaterialProgressBarRenderer : ViewRenderer<ProgressBar, MProgressView>
{
const float BackgroundAlpha = 0.3f;
const float BackgroundAlpha = 0.6f;

BasicColorScheme _defaultColorScheme;
BasicColorScheme _colorScheme;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
using AProgressBar = Android.Widget.ProgressBar;
using AView = Android.Views.View;

[assembly: ExportRenderer(typeof(Xamarin.Forms.ProgressBar), typeof(MaterialProgressBarRenderer), new[] { typeof(VisualRendererMarker.Material) })]
[assembly: ExportRenderer(typeof(ProgressBar), typeof(MaterialProgressBarRenderer), new[] { typeof(VisualRendererMarker.Material) })]

namespace Xamarin.Forms.Platform.Android.Material
{
public class MaterialProgressBarRenderer : AProgressBar,
IVisualElementRenderer, IViewRenderer, ITabStop
{
const float BackgroundAlpha = 0.6f;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this constant should be moved to the MaterialColors type (as the rest of the values like this are there)

const int MaximumValue = 10000;

int? _defaultLabelFor;
Expand All @@ -28,6 +29,8 @@ public class MaterialProgressBarRenderer : AProgressBar,

ProgressBar _element;

AColor _defaultPrimaryColor => MaterialColors.Light.PrimaryColor;

VisualElementTracker _visualElementTracker;
VisualElementRenderer _visualElementRenderer;
MotionEventHelper _motionEventHelper;
Expand Down Expand Up @@ -122,7 +125,6 @@ protected virtual void OnElementChanged(ElementChangedEventArgs<ProgressBar> e)
protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
ElementPropertyChanged?.Invoke(this, e);

if (e.PropertyName == ProgressBar.ProgressProperty.PropertyName)
UpdateProgress();
else if (e.PropertyName == ProgressBar.ProgressColorProperty.PropertyName || e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
Expand All @@ -142,51 +144,13 @@ void UpdateColors()
if (Element == null || Control == null)
return;

Color progressColor = Element.ProgressColor;
Color backgroundColor = Element.BackgroundColor;

var defaultProgress = MaterialColors.Light.PrimaryColor;

if (progressColor.IsDefault && backgroundColor.IsDefault)
{
// reset everything to defaults
ProgressTintList = ColorStateList.ValueOf(defaultProgress);
ProgressBackgroundTintList = ColorStateList.ValueOf(defaultProgress);
ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn;
}
else if (progressColor.IsDefault && !backgroundColor.IsDefault)
{
// handle the case where only the background is set
var background = backgroundColor.ToAndroid();

// TODO: Potentially override primary color to match material design.
ProgressTintList = ColorStateList.ValueOf(defaultProgress);
ProgressBackgroundTintList = ColorStateList.ValueOf(background);

// TODO: Potentially override background alpha to match material design.
ProgressBackgroundTintMode = PorterDuff.Mode.SrcOver;
}
else if (!progressColor.IsDefault && backgroundColor.IsDefault)
{
// handle the case where only the progress is set
var progress = progressColor.ToAndroid();

ProgressTintList = ColorStateList.ValueOf(progress);
ProgressBackgroundTintList = ColorStateList.ValueOf(progress);
ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn;
}
else
{
// handle the case where both are set
var background = backgroundColor.ToAndroid();
var progress = progressColor.ToAndroid();

ProgressTintList = ColorStateList.ValueOf(progress);
ProgressBackgroundTintList = ColorStateList.ValueOf(background);

// TODO: Potentially override alpha to match material design.
ProgressBackgroundTintMode = PorterDuff.Mode.SrcOver;
}
var primary = Element.ProgressColor.IsDefault ? _defaultPrimaryColor : Element.ProgressColor.ToAndroid();
ProgressTintList = ColorStateList.ValueOf(primary);
var background = Element.BackgroundColor.IsDefault
? new AColor(primary.R, primary.G, primary.B, (byte)(BackgroundAlpha * primary.A))
: Element.BackgroundColor.ToAndroid();
ProgressBackgroundTintList = ColorStateList.ValueOf(background);
ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn;
paymicro marked this conversation as resolved.
Show resolved Hide resolved
}

void UpdateProgress()
Expand All @@ -207,7 +171,7 @@ void UpdateProgress()
SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint)
{
Measure(widthConstraint, heightConstraint);
return new SizeRequest(new Size(Control.MeasuredWidth, Control.MeasuredHeight), new Size());
return new SizeRequest(new Size(Control.MeasuredWidth, Context.ToPixels(4)), new Size(Context.ToPixels(4), Context.ToPixels(4)));
}

void IVisualElementRenderer.SetElement(VisualElement element) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
From original drawable https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/drawable/progress_horizontal_material.xml
with removed rounded corners.
paymicro marked this conversation as resolved.
Show resolved Hide resolved
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
android:gravity="center_vertical|fill_horizontal">
<shape android:shape="rectangle"
android:tint="#000">
<corners android:radius="0dp" />
<solid android:color="#000" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress"
android:gravity="center_vertical|fill_horizontal">
<scale android:scaleWidth="100%">
<shape android:shape="rectangle"
android:tint="#000">
<corners android:radius="0dp" />
<solid android:color="#000" />
</shape>
</scale>
</item>
<item android:id="@android:id/progress"
android:gravity="center_vertical|fill_horizontal">
<scale android:scaleWidth="100%">
<shape android:shape="rectangle"
android:tint="#000">
<corners android:radius="0dp" />
<solid android:color="#000" />
</shape>
</scale>
</item>
</layer-list>
2 changes: 2 additions & 0 deletions Xamarin.Forms.Platform.Android/Resources/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

<!-- Material Progress Bars -->
<style name="XamarinFormsMaterialProgressBarHorizontal" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@drawable/MaterialProgressBar</item>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you opt to use the base control and a custom drawing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just got reminded by Shane, Google has a HARD set for 4dp. Of course, this is absolutely not true for iOS, but hey, why follow your own guides.

</style>
<style name="XamarinFormsMaterialProgressBarCircular" parent="Widget.AppCompat.ProgressBar">
<item name="android:background">@drawable/MaterialActivityIndicatorBackground</item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\MaterialProgressBar.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<Target Name="BeforeBuild" Condition=" '$(CreateAllAndroidTargets)' == 'true' ">
<!-- create 8.1 binaries-->
<MSBuild Targets="Restore" Projects="@(ProjectToBuild)">
Expand Down