Плавающая кнопка действия в Xamarin.Forms

Я заполнил домашнюю страницу своего приложения в Xamarin.Forms Portable.

Теперь я хочу добавить кнопку действия Flotation в моем проекте Android!

Есть ли способ добавить FAB для Android на мою домашнюю страницу, которая была написана в Xamarin.Forms Portable.

ИЛИ ЖЕ

Я хочу создать отдельную домашнюю страницу для Android и добавить ее в качестве главной страницы для Android?

Спасибо и С уважением.

2 ответа

Решение

Перед выходом официальной библиотеки поддержки я перенес FAB.

Теперь в моем репозитории GitHub есть образец Xamarin.Forms, который вы можете использовать: https://github.com/jamesmontemagno/FloatingActionButton-for-Xamarin.Android

Создание пользовательского элемента управления Чтобы свойства FAB могли быть привязаны в Xamarin.Forms, нам нужен настраиваемый элемент управления с привязываемыми свойствами.

public class FloatingActionButtonView : View
{
    public static readonly BindableProperty ImageNameProperty = BindableProperty.Create<FloatingActionButtonView,string>( p => p.ImageName, string.Empty);
    public string ImageName 
    {
      get { return (string)GetValue (ImageNameProperty); } 
      set { SetValue (ImageNameProperty, value); } 
    }

    public static readonly BindableProperty ColorNormalProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorNormal, Color.White);
    public Color ColorNormal 
    {
      get { return (Color)GetValue (ColorNormalProperty); } 
      set { SetValue (ColorNormalProperty, value); } 
    }

    public static readonly BindableProperty ColorPressedProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorPressed, Color.White);
    public Color ColorPressed 
    {
      get { return (Color)GetValue (ColorPressedProperty); } 
      set { SetValue (ColorPressedProperty, value); } 
    }

    public static readonly BindableProperty ColorRippleProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorRipple, Color.White);
    public Color ColorRipple 
    {
      get { return (Color)GetValue (ColorRippleProperty); } 
      set { SetValue (ColorRippleProperty, value); } 
    }
    ...
}

Затем мы сопоставим каждое свойство с соответствующим свойством в собственном элементе управления FAB.

Прикрепить рендерер

Если мы хотим использовать собственный элемент управления в Xamarin.Forms, нам нужен рендерер. Для простоты, давайте использовать ViewRenderer, Этот рендер будет отображать наш пользовательский FloatingActionButtonView для Android.Widget.FrameLayout,

public class FloatingActionButtonViewRenderer : ViewRenderer<FloatingActionButtonView, FrameLayout>
{
    ...
    private readonly Android.Content.Context context;
    private readonly FloatingActionButton fab;

    public FloatingActionButtonViewRenderer()
    {
        context = Xamarin.Forms.Forms.Context;
        fab = new FloatingActionButton(context);
        ...
    }

    protected override void OnElementChanged(ElementChangedEventArgs<FloatingActionButtonView> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null || this.Element == null)
            return;

        if (e.OldElement != null)
            e.OldElement.PropertyChanged -= HandlePropertyChanged;

        if (this.Element != null) {
            //UpdateContent ();
            this.Element.PropertyChanged += HandlePropertyChanged;
        }

        Element.Show = Show;
        Element.Hide = Hide;

        SetFabImage(Element.ImageName);

        fab.ColorNormal = Element.ColorNormal.ToAndroid();
        fab.ColorPressed = Element.ColorPressed.ToAndroid();
        fab.ColorRipple = Element.ColorRipple.ToAndroid();

        var frame = new FrameLayout(Forms.Context);
        frame.RemoveAllViews();
        frame.AddView(fab);

        SetNativeControl (frame);
    }

    public void Show(bool animate = true)
    {
        fab.Show(animate);
    }

    public void Hide(bool animate = true)
    {
        fab.Hide(animate);
    }

    void HandlePropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Content") {
            Tracker.UpdateLayout ();
        } 
        else if (e.PropertyName == FloatingActionButtonView.ColorNormalProperty.PropertyName) 
        {
            fab.ColorNormal = Element.ColorNormal.ToAndroid();
        } 
        else if (e.PropertyName == FloatingActionButtonView.ColorPressedProperty.PropertyName) 
        {
            fab.ColorPressed = Element.ColorPressed.ToAndroid();
        } 
        else if (e.PropertyName == FloatingActionButtonView.ColorRippleProperty.PropertyName) 
        {
            fab.ColorRipple = Element.ColorRipple.ToAndroid();
        }
        ...
    }

    void SetFabImage(string imageName)
    {
        if(!string.IsNullOrWhiteSpace(imageName))
        {
            try
            {
                var drawableNameWithoutExtension = Path.GetFileNameWithoutExtension(imageName);
                var resources = context.Resources;
                var imageResourceName = resources.GetIdentifier(drawableNameWithoutExtension, "drawable", context.PackageName);
                fab.SetImageBitmap(Android.Graphics.BitmapFactory.DecodeResource(context.Resources, imageResourceName));
            }
            catch(Exception ex)
            {
                throw new FileNotFoundException("There was no Android Drawable by that name.", ex);
            }
        }
    }
}

Потяните все вместе

ХОРОШО! Мы создали пользовательский элемент управления и сопоставили его с визуализатором. Последний шаг - это наложение контроля, на наш взгляд.

public class MainPage : ContentPage
{
    public MainPage()
    {
        var fab = new FloatingActionButtonView() {
            ImageName = "ic_add.png",
            ColorNormal = Color.FromHex("ff3498db"),
            ColorPressed = Color.Black,
            ColorRipple = Color.FromHex("ff3498db")
        };

        // Main page layout
        var pageLayout = new StackLayout {
            Children = 
            {
                new Label {
                    VerticalOptions = LayoutOptions.CenterAndExpand,
                    XAlign = TextAlignment.Center,
                    Text = "Welcome to Xamarin Forms!" 
                }
            }};

        var absolute = new AbsoluteLayout() { 
            VerticalOptions = LayoutOptions.FillAndExpand, 
            HorizontalOptions = LayoutOptions.FillAndExpand };

        // Position the pageLayout to fill the entire screen.
        // Manage positioning of child elements on the page by editing the pageLayout.
        AbsoluteLayout.SetLayoutFlags(pageLayout, AbsoluteLayoutFlags.All);
        AbsoluteLayout.SetLayoutBounds(pageLayout, new Rectangle(0f, 0f, 1f, 1f));
        absolute.Children.Add(pageLayout);

        // Overlay the FAB in the bottom-right corner
        AbsoluteLayout.SetLayoutFlags(fab, AbsoluteLayoutFlags.PositionProportional);
        AbsoluteLayout.SetLayoutBounds(fab, new Rectangle(1f, 1f, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
        absolute.Children.Add(fab);

        Content = absolute;
    }
}

Полный код на Github: кнопка с плавающим действием Xamarin.Forms

Другие вопросы по тегам