forked from tbaggett/xfgloss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadme.txt
617 lines (434 loc) · 23 KB
/
readme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
(Content from https://github.com/tbaggett/xfgloss/blob/master/README.md)
XFGloss: Xamarin.Forms UI Enhancements
XFGloss adds new properties to the Xamarin.Forms standard UI components on the Android and
iOS platforms. It uses attached bindable properties and enhanced platform-specific
renderers to work its magic. More details are available here.
Building XFGloss requires Visual Studio 2015 with update 3 installed on the Windows
platform, or Xamarin Studio 6.0 on the Mac platform. A nuget package is also available for
easy inclusion into your Xamarin.Forms projects. See the “Adding XFGloss to Your Xamarin.Forms-Based App” section below for the needed integration steps.
==========================================================================================
A gradient background can be added to a XF ContentPage by adding this code to the Xaml
declaration:
<?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:xfg="clr-namespace:XFGloss;assembly=XFGloss"
x:Class="XFGlossSample.Views.AboutPage"
Title="XFGloss Sample App" Padding="10"
>
<xfg:ContentPageGloss.BackgroundGradient>
<xfg:Gradient Rotation="150">
<xfg:GradientStep StepColor="White" StepPercentage="0" />
<xfg:GradientStep StepColor="White" StepPercentage=".5" />
<xfg:GradientStep StepColor="#ccd9ff" StepPercentage="1" />
</xfg:Gradient>
</xfg:ContentPageGloss.BackgroundGradient>
...
</ContentPage>
XFGloss properties can also be constructed in code. Here's the C# equivalent for the above
Xaml.
namespace XFGlossSample.Views
{
public class AboutPage : ContentPage
{
public AboutPage()
{
Title = "XFGloss Sample App";
Padding = 10;
// Manually construct a multi-color gradient at an angle of our choosing
var bkgrndGradient = new Gradient()
{
Rotation = 150,
Steps = new GradientStepCollection()
{
new GradientStep(Color.White, 0),
new GradientStep(Color.White, .5),
new GradientStep(Color.FromHex("#ccd9ff"), 1)
}
};
ContentPageGloss.SetBackgroundGradient(this, bkgrndGradient);
Content = { ... }
}
}
}
You can also instantiate an XFGloss instance to make multiple assignments easier. Note
that the gloss instance doesn't have to be retained. It only provides convenient access to
the static setters.
// Create a XF Switch component and apply some gloss to it
var onOffSwitch = new Switch();
var gloss = new SwitchGloss(onOffSwitch);
gloss.TintColor = Color.Red;
gloss.ThumbTintColor = Color.Maroon;
gloss.OnTintColor = Color.Green;
gloss.ThumbOnTintColor = Color.Lime;
==========================================================================================
Sample App
The XFGloss solution provided in this repository also includes the "XFGlossSample"
Xamarin.Forms-based app. It demonstrates all the XFGloss properties being applied in both
Xaml and C# code.
==========================================================================================
New/Enhanced Properties Provided by XFGloss
Some of the properties added by XFGloss already exist on some XF components. For example,
the BackgroundColor property is available on many XF components. In such cases, XFGloss
adds those properties to other XF components that didn't previously offer them. Other
properties like the BackgroundGradient property are completely new to the XF environment.
Here's a brief description of the properties added/expanded by XFGloss:
------------------------------------------------------------------------------------------
AccessoryType (iOS only)
Type: XFGloss.CellGlossAccessoryType enum value
Added to: EntryCell, ImageCell, TextCell and ViewCell
Allows specifying the accessory type to be shown on the right side of the cell. Possible
values are None, DisclosureIndicator, Checkmark and EditIndicator.
The Android platform doesn't offer accessory types as part of its standard UI, so this
property is ignored on Android devices.
The iOS DetailButton and DetailDisclosureButton accessory types aren't currently supported
due to Xamarin.Forms' ListView component not allowing the external access needed to react
to the user tapping the Details button. I plan to submit a PR that will address this, and
will add support for those types to XFGloss once the needed access is available.
The XF TableView component already provides the needed access, so I could add support for
those accessory types for use with the TableView only if it is needed in the meantime.
Please submit an issue if you would like the TableView-only property to be added before
ListView also supports it.
Xaml Example:
<TextCell Text="DisclosureIndicator" xfg:CellGloss.AccessoryType="DisclosureIndicator" />
C# Example:
var cell = new TextCell();
cell.Text = "DisclosureIndicator";
CellGloss.SetAccessoryType(cell, CellGlossAccessoryType.DisclosureIndicator);
------------------------------------------------------------------------------------------
BackgroundColor
Type: Xamarin.Forms Color
Added to: EntryCell, ImageCell, SwitchCell, TextCell and ViewCell
Allows a color value to be specified as a cell's background color. Possible values are
either named colors or numeric color values.
Xaml Example:
<TextCell Text="Red" xfg:CellGloss.BackgroundColor="Red" />
C# Example:
var cell = new TextCell();
cell.Text = "Red";
CellGloss.SetBackgroundColor(cell, Color.Red);
------------------------------------------------------------------------------------------
BackgroundGradient
Type: XFGloss.Gradient
Added to: ContentPage, EntryCell, ImageCell, SwitchCell, TextCell and ViewCell
Allows a multiple-color linear gradient to be specified as a content page or cells'
background. You can specify as many colors as you like and control their distribution
across the fill at any angle. Convenience properties and constructors also make it easy to
create two-color horizontal or vertical fills.
Xaml Example:
<TextCell Text="Red" TextColor="White">
<xfg:CellGloss.BackgroundGradient>
<xfg:Gradient StartColor="Red" EndColor="Maroon" IsRotationTopToBottom="true" />
</xfg:CellGloss.BackgroundGradient>
</TextCell>
<TextCell Text="All Three" TextColor="White" x:Name="rotatingCell">
<!-- You can also create gradients at any angle with as many steps as you want. -->
<xfg:CellGloss.BackgroundGradient>
<xfg:Gradient Rotation="135" x:Name="rotatingGradient">
<xfg:GradientStep StepColor="Red" StepPercentage="0" />
<xfg:GradientStep StepColor="Maroon" StepPercentage=".25" />
<xfg:GradientStep StepColor="Lime" StepPercentage=".4" />
<xfg:GradientStep StepColor="Green" StepPercentage=".6" />
<xfg:GradientStep StepColor="Blue" StepPercentage=".75" />
<xfg:GradientStep StepColor="Navy" StepPercentage="1" />
</xfg:Gradient>
</xfg:CellGloss.BackgroundGradient>
</TextCell>
C# Example:
var cell = new TextCell();
cell.Text = "Red";
cell.TextColor = Color.White;
CellGloss.SetBackgroundGradient(cell, new Gradient(Color.Red, Color.Maroon,
Gradient.RotationTopToBottom));
// Manually construct a multi-color gradient at an angle of our choosing
var rotatingCell = new TextCell();
rotatingCell.Text = "All Three";
rotatingCell.TextColor = Color.White;
var rotatingGradient = new Gradient(135); // 135 degree angle
rotatingGradient.AddStep(Color.Red, 0);
rotatingGradient.AddStep(Color.Maroon, .25);
rotatingGradient.AddStep(Color.Lime, .4);
rotatingGradient.AddStep(Color.Green, .6);
rotatingGradient.AddStep(Color.Blue, .75);
rotatingGradient.AddStep(Color.Navy, 1);
CellGloss.SetBackgroundGradient(rotatingCell, rotatingGradient);
------------------------------------------------------------------------------------------
MaxTrackTintColor
MaxTrackTintColor Example
Type: Xamarin.Forms.Color
Added to: Slider
Allows a color value to be specified for a Slider's right side of the track, beginning at
the current thumb position. Possible values are either named colors or numeric color
values.
KNOWN ISSUE: Modifying this property has no effect on an Android device running API 21
(Lollipop). Android's native support for this property is broken in that API level. This
property works as expected on Android devices running all other API levels between 16
(Jelly Bean) and 23 (Marshmallow).
Xaml Example:
<Slider Minimum="0" Maximum="100" Value="25" xfg:SliderGloss.MaxTrackTintColor="Red" />
C# Example:
var slider = new Slider { Minimum = 0, Maximum = 100, Value = 25 };
SliderGloss.SetMaxTrackTintColor(slider, Color.Red);
------------------------------------------------------------------------------------------
MinTrackTintColor
Type: Xamarin.Forms.Color
Added to: Slider
Allows a color value to be specified for a Slider's left side of the track, up to the
current thumb position. Possible values are either named colors or numeric color values.
KNOWN ISSUE: Modifying this property causes both the left and right sides of the track's
colors to be changed on Android devices running API 21 (Lollipop). Android's native
support for this property was incorrectly implemented in that API level. This property
works as expected on Android devices running all other API levels between 16 (Jelly Bean)
and 23 (Marshmallow).
Xaml Example:
<Slider Minimum="0" Maximum="100" Value="25" xfg:SliderGloss.MinTrackTintColor="Red" />
C# Example:
var slider = new Slider { Minimum = 0, Maximum = 100, Value = 25 };
SliderGloss.SetMinTrackTintColor(slider, Color.Red);
------------------------------------------------------------------------------------------
OnTintColor
Type: Xamarin.Forms Color
Added to: Switch and SwitchCell
Allows a color value to be specified as the Switch control's track color when it is in the
"on" position for the Switch and SwitchCell classes. Possible values are either named
colors or numeric color values.
Xaml Example:
<SwitchCell Text="Red" xfg:SwitchCellGloss.OnTintColor="Red" />
<Switch xfg:SwitchGloss.OnTintColor="Red" />
C# Example:
var cell = new SwitchCell();
cell.Text = "Red";
SwitchCellGloss.SetOnTintColor(cell, Color.Red);
var switchCtrl = new Switch();
SwitchGloss.SetOnTintColor(switchCtrl, Color.Red);
------------------------------------------------------------------------------------------
ThumbOnTintColor
Type: Xamarin.Forms Color
Added to: Switch and SwitchCell
Allows a color value to be specified as the Switch control's thumb color when it is in the
"on" position for the Switch and SwitchCell classes. Possible values are either named
colors or numeric color values.
Xaml Example:
<SwitchCell Text="Red" xfg:SwitchCellGloss.ThumbOnTintColor="Red" />
<Switch xfg:SwitchGloss.ThumbOnTintColor="Red" />
C# Example:
var cell = new SwitchCell();
cell.Text = "Red";
SwitchCellGloss.SetThumbOnTintColor(cell, Color.Red);
var switchCtrl = new Switch();
SwitchGloss.SetThumbOnTintColor(switchCtrl, Color.Red);
------------------------------------------------------------------------------------------
ThumbTintColor
Type: Xamarin.Forms Color
Added to: Slider, Switch and SwitchCell
Allows a color value to be specified as the Slider control's thumb color as well as the
Switch control's thumb color when it is in the "off" position for the Switch and
SwitchCell classes. Possible values are either named colors or numeric color values.
Xaml Example:
<SwitchCell Text="Red" xfg:SwitchCellGloss.ThumbTintColor="Red" />
<Switch xfg:SwitchGloss.ThumbTintColor="Red" />
C# Example:
var cell = new SwitchCell();
cell.Text = "Red";
SwitchCellGloss.SetThumbTintColor(cell, Color.Red);
var switchCtrl = new Switch();
SwitchGloss.SetThumbTintColor(switchCtrl, Color.Red);
------------------------------------------------------------------------------------------
TintColor
Type: Xamarin.Forms Color
Added to: All cell classes' accessory types (iOS only), and the Switch and SwitchCell
components (both platforms)
Allows a color value to be specified as the Switch control's track color when it is in the
"off" position for the Switch and SwitchCell classes, and for the accessory view on iOS.
Possible values are either named colors or numeric color values.
Xaml Example:
<TextCell Text="Red" xfg:CellGloss.TintColor="Red" xfg:CellGloss.AccessoryType="Checkmark"
/>
<SwitchCell Text="Red" xfg:CellGloss.TintColor="Red" />
<Switch xfg:SwitchGloss.TintColor="Red" />
C# Example:
// iOS AccessoryType
var cell = new TextCell();
cell.Text = "Red";
var gloss = new CellGloss(cell);
gloss.TintColor = Color.Red;
gloss.AccessoryType = CellGlossAccessoryType.Checkmark;
// SwitchCell
var switchCell = new SwitchCell();
switchCell.Text = "Red";
CellGloss.SetTintColor(switchCell, Color.Red);
// Switch
var switchCtrl = new Switch();
SwitchGloss.SetTintColor(switchCtrl, Color.Red);
==========================================================================================
Adding XFGloss to Your Xamarin.Forms-Based App
Integrating XFGloss into your XF-based app is easy. First, add the XFGloss NuGet package
to your app's PCL and Android/iOS platform projects. Next, initialize XFGloss from each of
the platform projects, like so:
Android MainActivity.cs:
namespace XFGlossSample.Droid
{
[Activity(Label = "XFGlossSample.Droid", Icon = "@drawable/icon", Theme =
"@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize |
ConfigChanges.Orientation)]
public class MainActivity :
global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
// IMPORTANT: Initialize XFGloss AFTER calling LoadApplication on the Android
platform
XFGloss.Droid.Library.Init(this, savedInstanceState);
}
}
}
iOS AppDelegate.cs:
namespace XFGlossSample.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate :
global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Xamarin.Forms.Forms.Init();
/********** ADD THIS CALL TO INITIALIZE XFGloss *********/
XFGloss.iOS.Library.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
}
Next, add a namespace entry to your Xaml files, or a using statement to your C# files, and
start adding the new XFGloss properties to Xamarin.Forms components as demonstrated here
and in the XFGlossSample app's source code.
XML namespace declaration needed in Xaml files:
xmlns:xfg="clr-namespace:XFGloss;assembly=XFGloss"
Using statement needed in C# files:
using XFGloss;
Using XFGloss With the Android AppCompat Package
XFGloss has been tested with Android APIs 16 (Jelly Bean) through 23 (Marshmallow). The
Android AppCompat library is required for Android devices running APIs prior to
Marshmallow. In such cases, the XFGloss features that depend on the AppCompat library will
fail gracefully if the application's main activity doesn't extend the XF
FormsAppCompatActivity class.
XFGloss also provides a new SwitchCell renderer for the Android platform when using the
AppCompat library. The new renderer utilizes the SwitchCompat component instead of the
standard Android Switch control, resulting in a material design styled switch instead of
the previous styling, as seen below.
This option can be disabled if the previous styling is preferred. However, the custom
XFGloss tinting properties will not be applied if the standard SwitchCell renderer is
used.
To disable the use of the SwitchCompat-based renderer, set the
XFGloss.Droid.Library.UsingSwitchCompatCell property to false BEFORE calling the Init
method, like so:
Android MainActivity.cs:
XFGloss.Droid.Library.UsingSwitchCompatCell = false;
// IMPORTANT: Initialize XFGloss AFTER calling LoadApplication on the Android platform
XFGloss.Droid.Library.Init(this, savedInstanceState);
Using XFGloss with Other Custom XF Controls
==========================================================================================
XFGloss should work with existing custom XF controls provided that the following criteria
is met.
1. The ExportRenderer Attribute Should Not Map to Existing XF Controls
The ExportRenderer attribute tells the XF framework what code should be executed to create
and communicate with a platform-specific UI component when a given generic XF control is
used. Most tutorials/examples of making custom XF components show a ExportRenderer
attribute that maps a new generic XF control (the first typeof parameter in the attribute)
to a new platform-specific renderer (the second typeof parameter). Your existing custom
controls should work with XFGloss if that approach was used.
Existing custom controls with an ExportRenderer attribute like this should work:
[assembly: ExportRenderer(typeof(MyCustomSwitch), typeof(MyCustomSwitchRenderer))]
A custom control won't be compatible with XFGloss if the ExportRenderer attribute maps a
new custom renderer directly to an existing XF control. XFGloss uses this technique to
enhance the stock controls instead of creating new custom ones. XFGloss must be the only
case where custom renderers are mapped to standard XF controls. If there are multiple
mappings to the same XF control, the last mapping to be processed at runtime is the only
renderer that will be used.
Existing custom controls with an ExportRenderer attribute that maps directly to a stock XF
control (the Switch control in this example) won't work:
[assembly: ExportRenderer(typeof(Switch), typeof(MyCustomSwitchRenderer))]
2. Existing Renderers Should Inherit From XFGloss Renderers Where Applicable
To make XFGloss work with your custom component, change your custom renderers to inherit
from the XFGloss renderers instead of the Xamarin.Forms renderers.
For example, change:
public class MyCustomContentPageRenderer : PageRenderer
{
...
}
To:
public class MyCustomContentPageRenderer : XFGlossContentPageRenderer
{
...
}
A complete list of the XF renderers that are customized by XFGloss is provided below.
Change existing custom renderers to inherit from the XFGloss renderer if its current base
class is found in this list.
+----------------------------------------------------------------------------------------+
| XF Renderer | XFG Renderer | XFG Renderer on Android w/AppCompat |
| EntryCellRenderer | XFGlossEntryCellRenderer | |
| ImageCellRenderer | XFGlossImageCellRenderer | |
| PageRenderer* | XFGlossContentPageRenderer | |
| SliderRenderer | XFGlossSliderRenderer | |
| SwitchRenderer | XFGlossSwitchRenderer | XFGlossSwitchCompatRenderer |
| SwitchCellRenderer | XFGlossSwitchCellRenderer | XFGlossSwitchCompatCellRenderer |
| TextCellRenderer | XFGlossTextCellRenderer | |
| ViewCellRenderer | XFGlossViewCellRenderer | |
+----------------------------------------------------------------------------------------+
* PageRenderer inheritance should only be changed if the associated ExportRenderer
attribute is mapping the XF ContentPage control to a custom renderer. Mapping the XF Page
base class to custom renderers causes unstable behavior on the Android platform.
3. Existing Renderers Should Always Call the Base Class Versions of Overridden Methods
The XFGloss renderer classes require their overridden versions of OnElementChanged and
OnElementPropertyChanged methods to be called, as well as other overridable methods and
properties on a per-control basis. Verify your renderers are calling the base class
implementations of any overridden methods and properties if XFGloss isn't working as
expected.
==========================================================================================
Known Issues
The default XF EntryCell renderer on iOS doesn't take the accessory view into account when
positioning/sizing the text entry field. I plan to submit a PR that corrects this issue.
==========================================================================================
Future Enhancements
I plan to add support for other properties that aren't offered by the Xamarin.Forms
components as my schedule allows. PRs, especially those that add support for other
XF-supported platforms, are always welcomed!
==========================================================================================
Credits
XFGloss was inspired by "Lighting Up Native Platform Features In Xamarin Forms." Thanks
goes out to the series' author, Keith Rome, for the inspiration and starting point for
XFGloss.
Also, my skills with Xamarin were once again greatly improved this year by getting
recertified as a Xamarin Certified Mobile Developer after having been originally certified
in 2013. Here's a special shout out to some of my favorite XamU instructors, including
Glenn Stephens, Kym Phillpotts and Judy McNeil! They're all seasoned Xamarin developers
and great instructors. Thanks to all of you and the other XamU instructors for the great
training!
==========================================================================================
License
The MIT License (MIT)
Copyright (c) 2016 Ansuria Solutions LLC & Tommy Baggett
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
==========================================================================================
About the Author
I am a Xamarin Certified Mobile Developer focused on Android, iOS and tvOS application
development using Microsoft tools and C#, and Apple tools and Swift. I have 25+ years of
professional software development experience and have successfully telecommuted on a
variety of projects since 2008.