Sök…


Introduktion

Varje Xamarin.Forms vy har en åtföljande återgivare för varje plattform som skapar en instans av en egen kontroll. När en vy återges på den specifika plattformen ViewRenderer klassen.

Processen för att göra detta är följande:

Skapa en Xamarin.Forms anpassad kontroll.

Konsumera den anpassade kontrollen från Xamarin.Forms.

Skapa den anpassade renderaren för kontrollen på varje plattform.

Implementera en CheckBox-kontroll

I det här exemplet kommer vi att implementera en anpassad checkbox för Android och iOS.

Skapa den anpassade kontrollen

namespace CheckBoxCustomRendererExample
{
    public class Checkbox : View
    {
        public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create<Checkbox, bool>(p => p.IsChecked, true, propertyChanged: (s, o, n) => { (s as Checkbox).OnChecked(new EventArgs()); });
        public static readonly BindableProperty ColorProperty = BindableProperty.Create<Checkbox, Color>(p => p.Color, Color.Default);

        public bool IsChecked
        {
            get
            {
                return (bool)GetValue(IsCheckedProperty);
            }
            set
            {
                SetValue(IsCheckedProperty, value);
            }
        }

        public Color Color
        {
            get
            {
                return (Color)GetValue(ColorProperty);
            }
            set
            {
                SetValue(ColorProperty, value);
            }
        }

        public event EventHandler Checked;

        protected virtual void OnChecked(EventArgs e)
        {
            if (Checked != null)
                Checked(this, e);
        }
    }
}

Vi börjar med Android Custom Renderer genom att skapa en ny klass ( CheckboxCustomRenderer ) i Android delen av vår lösning.

Några viktiga detaljer att notera:

  • Vi måste markera toppen av vår klass med attributet ExportRenderer så att renderaren är registrerad hos Xamarin.Forms . På detta sätt kommer Xamarin.Forms att använda den här renderaren när den försöker skapa vårt Checkbox objekt på Android .
  • Vi gör det mesta av vårt arbete med OnElementChanged metoden, där vi initierar och ställer in vår egen kontroll.

Konsumerar den anpassade kontrollen

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CheckBoxCustomRendererExample" x:Class="CheckBoxCustomRendererExample.CheckBoxCustomRendererExamplePage">
    <StackLayout Padding="20">
        <local:Checkbox Color="Aqua" />
    </StackLayout>
</ContentPage>

Skapa den anpassade återgivaren på varje plattform

Processen för att skapa den anpassade återgivarklassen är enligt följande:

  1. Skapa en underklass i klassen ViewRenderer<T1,T2> som gör den anpassade kontrollen. Det första typargumentet bör vara den anpassade kontrollen som renderaren är för, i detta fall CheckBox . Det andra typargumentet bör vara den ursprungliga kontrollen som kommer att implementera den anpassade kontrollen.
  2. Överstyr metoden OnElementChanged som gör den anpassade kontrollen och skrivlogiken för att anpassa den. Den här metoden kallas när motsvarande Xamarin.Forms kontroll skapas.
  3. Lägg till ett ExportRenderer attribut till den anpassade återgivarklassen för att ange att det ska användas för att göra Xamarin.Forms anpassad kontroll. Detta attribut används för att registrera den anpassade renderaren med Xamarin.Forms .

Skapa den anpassade återgivaren för Android

[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.Droid
{
    public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBox>
    {
        private CheckBox checkBox;

        protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
        {
            base.OnElementChanged(e);
            var model = e.NewElement;
            checkBox = new CheckBox(Context);
            checkBox.Tag = this;
            CheckboxPropertyChanged(model, null);
            checkBox.SetOnClickListener(new ClickListener(model));
            SetNativeControl(checkBox);
        }
        private void CheckboxPropertyChanged(Checkbox model, String propertyName)
        {
            if (propertyName == null || Checkbox.IsCheckedProperty.PropertyName == propertyName)
            {
                checkBox.Checked = model.IsChecked;
            }

            if (propertyName == null || Checkbox.ColorProperty.PropertyName == propertyName)
            {
                int[][] states = {
                    new int[] { Android.Resource.Attribute.StateEnabled}, // enabled
                    new int[] {Android.Resource.Attribute.StateEnabled}, // disabled
                    new int[] {Android.Resource.Attribute.StateChecked}, // unchecked
                    new int[] { Android.Resource.Attribute.StatePressed}  // pressed
                };
                var checkBoxColor = (int)model.Color.ToAndroid();
                int[] colors = {
                    checkBoxColor,
                    checkBoxColor,
                    checkBoxColor,
                    checkBoxColor
                };
                var myList = new Android.Content.Res.ColorStateList(states, colors);
                checkBox.ButtonTintList = myList;

            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (checkBox != null)
            {
                base.OnElementPropertyChanged(sender, e);

                CheckboxPropertyChanged((Checkbox)sender, e.PropertyName);
            }
        }

        public class ClickListener : Java.Lang.Object, IOnClickListener
        {
            private Checkbox _myCheckbox;
            public ClickListener(Checkbox myCheckbox)
            {
                this._myCheckbox = myCheckbox;
            }
            public void OnClick(global::Android.Views.View v)
            {
                _myCheckbox.IsChecked = !_myCheckbox.IsChecked;
            }
        }
    }
}

Skapa den anpassade återgivaren för iOS

Eftersom det i iOS inte är en inbyggd kryssruta kommer vi att skapa en CheckBoxView först och sedan skapa en renderer för vår Xamarin.Forms-kryssruta.

CheckBoxView är baserat på två bilder check_checkbox.png och unchecked_checkbox.png så att egenskapen Color ignoreras.

CheckBox-vyn:

namespace CheckBoxCustomRendererExample.iOS
{        
    [Register("CheckBoxView")]
    public class CheckBoxView : UIButton
    {
        public CheckBoxView()
        {
            Initialize();
        }

        public CheckBoxView(CGRect bounds)
            : base(bounds)
        {
            Initialize();
        }

        public string CheckedTitle
        {
            set
            {
                SetTitle(value, UIControlState.Selected);
            }
        }

        public string UncheckedTitle
        {
            set
            {
                SetTitle(value, UIControlState.Normal);
            }
        }

        public bool Checked
        {
            set { Selected = value; }
            get { return Selected; }
        }

        void Initialize()
        {
            ApplyStyle();

            TouchUpInside += (sender, args) => Selected = !Selected;
            // set default color, because type is not UIButtonType.System 
            SetTitleColor(UIColor.DarkTextColor, UIControlState.Normal);
            SetTitleColor(UIColor.DarkTextColor, UIControlState.Selected);
        }

        void ApplyStyle()
        {
            SetImage(UIImage.FromBundle("Images/checked_checkbox.png"), UIControlState.Selected);
            SetImage(UIImage.FromBundle("Images/unchecked_checkbox.png"), UIControlState.Normal);
        }
    }
}

CheckBox anpassad återgivare:

[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.iOS
{
    public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBoxView>
    {

        /// <summary>
        /// Handles the Element Changed event
        /// </summary>
        /// <param name="e">The e.</param>
        protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
        {
            base.OnElementChanged(e);

            if (Element == null)
                return;

            BackgroundColor = Element.BackgroundColor.ToUIColor();
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                    var checkBox = new CheckBoxView(Bounds);
                    checkBox.TouchUpInside += (s, args) => Element.IsChecked = Control.Checked;
                    SetNativeControl(checkBox);
                }
                Control.Checked = e.NewElement.IsChecked;
            }

            Control.Frame = Frame;
            Control.Bounds = Bounds;

        }

        /// <summary>
        /// Handles the <see cref="E:ElementPropertyChanged" /> event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName.Equals("Checked"))
            {
                Control.Checked = Element.IsChecked;
            }
        }
    }
}

Resultat:

ange bildbeskrivning här ange bildbeskrivning här



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow