Use of Xamarin.Forms's effects

Source: Internet
Author: User

In Xamarin.Forms 2.1.0-pre1, Xamarin.Forms added a new effects API. Effects is a series of methods that add runtime changes to a view's renderer.

However, I would like to emphasize that effects are inherently designed to be highly reusable. If a effect can solve a problem, it may be able to be used throughout your app. If you write a effect to solve one of your problems, you can share it with other people who meet the same problem. This article attempts to demonstrate a way to help us make it easy to share effects.

public class shadoweffect:platformeffect{protected override void OnAttached ( ) {updatesize (); UpdateColor (); Updateopacity ();} protected override void Ondetached () {Container.Layer.ShadowOpacity = 0;} protected override void Onelementpropertychanged (PropertyChangedEventArgs e) {Debug.WriteLine (E.propertyname), if (E. PropertyName = = ViewExtensions.HasShadowProperty.PropertyName) {updateopacity ();} else if (E.propertyname = = ViewExtensions.ShadowColorProperty.PropertyName) {UpdateColor ();} else if (E.propertyname = = ViewExtensions.ShadowSizeProperty.PropertyName) {updatesize ();}} private void Updateopacity () {Container.Layer.ShadowOpacity = Viewextensions.gethasshadow (Element)? 1:0;} private void UpdateColor () {var color = Viewextensions.getshadowcolor (Element); Container.Layer.ShadowColor = color. Tocgcolor ();} private void Updatesize () {Container.Layer.ShadowRadius = (nfloat) viewextensions.getshadowsize (Element);}} 

The above code is really too much, we can use the following way:

public class shadoweffect:platformeffect{protected override void Onattached () {Container.Layer.ShadowOpacity = 1; Container.Layer.ShadowColor = UIColor.Black.ToCGColor; Container.Layer.ShadowRadius = 6;} protected override void Ondetached () {Container.Layer.ShadowOpacity = 0;}}

  

Writing effects in this way is very simple, but it also makes it impossible for us to easily configure it and reuse it. This approach is more like the customrenderer of the previous study.

Shadoweffect inherits from Platformeffect, which is located in a project on a specific platform. The implementation of the custom renderers,platformeffects is in a project on a specific platform, however the effect API is completely cross-platform, but is implemented using different parameters in a particular platform PlatformEffect<T, T>  . One of the main differences is that Effects Does not contain the type information of the container/control/element that it attaches, because they can be attached to any feature (element). When effect is attached to an unsupported feature (element), it is gracefully Degrade or throws an exception.

If the library contains effect, there are two important attributes that need to be set:

    • [assembly: ResolutionGroupName ("你的公司名称")]: Used to set a company name for your effects to prevent conflicts with other effects of the same name. You can set the same company name in multiple assemblies.
    • [assembly: ExportEffect (typeof (ShadowEffect), "ShadowEffect")]: Use to set a unique ID for your effect, and locate effect with the company name and the unique ID above.

Simple usage:

Adding a effect to your view is simple:

var button = New Button {Text = "I have a Shadow"};button. Effects.add (Effect.resolve ("Yourcompany.shadoweffect"));

  

If you do not implement a effect for a particular platform. The Effect.resolve method returns a non-null value that has no effect. This setting is useful for adding Effect to a platform rather than all platforms, but with minimal memory loss.

public static class Vieweffects{public static readonly Bindableproperty Hasshadowproperty = Bindableproperty.createattached ("Hasshadow", typeof (BOOL), typeof (Vieweffects), False, propertychanged: onhasshadowchanged);p rivate static void Onhasshadowchanged (Bindableobject bindable, Object OldValue, Object NewValue) { var view = bindable as view;if (view = = null) Return;var Hasshadow = (bool) newvalue;if (Hasshadow) {view. Effects.add (New Shadoweffect ());} else {var toremove = view. Effects.firstordefault (E = e is shadoweffect); if (toremove! = null) view. Effects.remove (Toremove);}} public static readonly Bindableproperty shadowsizeproperty =bindableproperty.createattached ("Shadowsize", typeof ( Double), typeof (Vieweffects), 0d);p ublic static readonly Bindableproperty Shadowcolorproperty = Bindableproperty.createattached ("Shadowcolor", typeof (Color), typeof (Vieweffects), color.default);p ublic static void Sethasshadow (Bindableobject view, bool Hasshadow) {view. SetValue (HasshadowproperTy, Hasshadow);} public static bool Gethasshadow (Bindableobject view) {return (bool) view. GetValue (Hasshadowproperty);} public static void setShadowSize (Bindableobject view, double size) {view. SetValue (shadowsizeproperty, size);} public static double getshadowsize (Bindableobject view) {return (double) view. GetValue (Shadowsizeproperty);} public static void setShadowColor (Bindableobject view, color color) {view. SetValue (shadowcolorproperty, color);} public static Color getShadowColor (Bindableobject view) {return (color) view. GetValue (Shadowcolorproperty);} Class Shadoweffect:routingeffect{public Shadoweffect (): Base ("Xamarin.shadoweffect") {}}}

It looks like a lot of code, actually only three additional attributes (attached BindableProperty s) and a few static getter and setter. The only bit of code that's complicated is OnHasShadowChanged,它里面根据附加属性的值来简单的添加或者移除Effect . Finally, The code uses Routingeffect instead of calling the Effect.resolve method directly, just to make the separation process simpler because the method does not get compile time for the type information for a particular platform.

How to use effect:

<button local:vieweffects.hasshadow= "True"         local:vieweffects.shadowcolor= "#222222"         Local: Vieweffects.shadowsize= "4"/>

Or better yet, use effect in style so you can apply effect to any/all of the buttons:

<style targettype= "button" >  <Style.Setters>    <setter property= "Local: Viewextensions.hasshadow "value=" True "/>    <setter property=" Local:ViewExtensions.ShadowColor "value=" # 232343 "/>    <setter property=" Local:ViewExtensions.ShadowSize "value=" 5 "/>  </Style.Setters> </Style>

  

Original address: http://xfcomplete.net/general/2016/01/20/using-effects/

Personal Understanding (16/2/1): Because the properties of the official controls in forms are very small, many times we need to use more properties, before the effects appear, We can only use Customrenderer to rewrite a control's rendering class (Viewrenderer) on a particular platform, for example, if you want to add a property pro_a to a control view_a, inherit view_a to write a subclass. In addition to writing renderer on a specific platform, you also need to reference <vewis:extendview_a in XAML when you use it.

If we use effect, we can write two effect directly, add effect on the basis of the official control <view_a, and the effect is completely generic, as long as the View supports this property, The effect can be used in a different view, not to mention a style that can be set globally or locally.

Use of Xamarin.Forms's effects

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.