代码之家  ›  专栏  ›  技术社区  ›  Rickless

当父级滚动时隐藏浮动操作按钮

  •  2
  • Rickless  · 技术社区  · 6 年前

    我正在创建一个自定义 FAB 两个按钮 android iOS 平台使用 Xamarin.Forms .

    一切都很好,但现在我想以某种方式得到 scrolled 最近父级的事件 绝妙的 如果有的话,我可以隐藏 绝妙的 当用户滚动时按钮,然后在滚动完成2秒后再次显示?.

    父级可以是普通的 ScrollView 或者它可能是一个 ListView .
    这可以通过每个平台的相同自定义渲染器实现吗?或者,这甚至可以实现吗?

    这就是我迄今为止所做的:

    1. FabButton 班级:


    public partial class FabButton : Button
    {
        public static BindableProperty ButtonColorProperty = BindableProperty.Create(nameof(ButtonColor), typeof(Color), typeof(FabButton), Color.Accent);
        public Color ButtonColor
        {
            get => (Color)GetValue(ButtonColorProperty);
            set => SetValue(ButtonColorProperty, value);
        }
        public FabButton()
        {
            InitializeComponent();
        }
    }
    
    1. 网间网操作系统 自定义呈现程序:

      public class FabButtonRenderer:ButtonRenderer
      {
          protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
          {
              base.OnElementChanged(e);
              if(e.NewElement == null)
                  return;
              if (Element.WidthRequest <= 0)
                  Element.WidthRequest = 60;
              if (Element.HeightRequest <= 0)
                  Element.HeightRequest = 60;
              if (Element.Margin == new Thickness(0, 0, 0, 0))
                  Element.Margin = new Thickness(0, 0, 20, 20);
              Element.CornerRadius = (int) Element.WidthRequest / 2;
              Element.BorderWidth = 0;
              Element.Text = null;
              Control.BackgroundColor = ((FabButton) Element).ButtonColor.ToUIColor();
          }
          public override void Draw(CGRect rect)
          {
              base.Draw(rect);
              Layer.ShadowRadius = 0.2f;
              Layer.ShadowColor = UIColor.Black.CGColor;
              Layer.ShadowOffset = new CGSize(1, 1);
              Layer.ShadowOpacity = 0.80f;
              Layer.ShadowPath = UIBezierPath.FromOval(Layer.Bounds).CGPath;
              Layer.MasksToBounds = false;
          }
          protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
          {
              base.OnElementPropertyChanged(sender, e);
              if (e.PropertyName == nameof(FabButton.ButtonColor))
                  Control.BackgroundColor = ((FabButton) Element).ButtonColor.ToUIColor();
          }
      }
      
    2. 安卓 自定义呈现程序:

      public class FabButtonRenderer: Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<FabButton,FloatingActionButton>
      {
          public static void InitRenderer() { }
          public FabButtonRenderer(Context context):base(context)
          {
      
          }
      
          protected override void OnElementChanged(ElementChangedEventArgs<FabButton> e)
          {
              base.OnElementChanged(e);
              if (e.NewElement == null)
                  return;
              if (e.NewElement.HeightRequest <= 0)
                  e.NewElement.HeightRequest = 85;
              if (e.NewElement.WidthRequest <= 0)
                  e.NewElement.WidthRequest = 75;
              if (e.NewElement.Margin.Equals(new Thickness(0, 0, 0, 0)))
                  e.NewElement.Margin = new Thickness(0, 0, 5, 10);
              var fabButton = new FloatingActionButton(Context);
              ViewCompat.SetBackgroundTintList(fabButton, ColorStateList.ValueOf(Element.ButtonColor.ToAndroid()));
              fabButton.UseCompatPadding = true;
              if (!string.IsNullOrEmpty(Element.Image?.File))
                  fabButton.SetImageDrawable(Context.GetDrawable(Element.Image.File));
              fabButton.Click += FabButton_Clicked;
              SetNativeControl(fabButton);
          }
      
          protected override void OnLayout(bool changed, int l, int t, int r, int b)
          {
              base.OnLayout(changed, l, t, r, b);
              Control.BringToFront();
          }
      
          protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
          {
              if (e.PropertyName == nameof(Element.ButtonColor))
                  ViewCompat.SetBackgroundTintList(Control, ColorStateList.ValueOf(Element.ButtonColor.ToAndroid()));
              if (e.PropertyName == nameof(Element.Image))
              {
                  if (!string.IsNullOrEmpty(Element.Image?.File))
                      Control.SetImageDrawable(Context.GetDrawable(Element.Image.File));
              }
              base.OnElementPropertyChanged(sender, e);
          }
      
          public void FabButton_Clicked(object sender, EventArgs e)
          {
              Element.SendClicked();
          }
      }
      
    2 回复  |  直到 6 年前
        1
  •  1
  •   Anmol Modi    6 年前

        2
  •  1
  •   Rickless    6 年前

    built-in
    Floating Action Button ScrollView
    MVVM
    IFloatingActionButtonHost

    public interface IFloatingActionButtonHost
    {
        bool ShouldBeHiddenWhenScrolling { get; }
        event Action LinkedScrollViewScrolled;
    }
    

    BindableProperty FabButton

    public static BindableProperty ButtonHostProperty = BindableProperty.Create(nameof(ButtonHost), typeof(IFloatingActionButtonHost), typeof(FabButton));
    public IFloatingActionButtonHost ButtonHost
    {
        get => (IFloatingActionButtonHost)GetValue(ButtonHostProperty);
        set => SetValue(ButtonHostProperty, value);
    }
    

    Renderer iOS

        var fabButton = (FabButton)Element;
        if (fabButton.ButtonHost != null && fabButton.ButtonHost.ShouldBeHiddenWhenScrolling)
        {
            fabButton.ButtonHost.LinkedScrollViewScrolled += OnLinkedScrollView_Scrolled;
        }
    


    private void OnLinkedScrollView_Scrolled()
    {
        Element.IsVisible = false;
        Device.StartTimer(TimeSpan.FromSeconds(3), () =>
        {
            if(Element != null){
                Element.IsVisible = true;
            }
            return false;
        });
    }
    

    OnElementPropertyChanged

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (e.PropertyName == nameof(FabButton.ButtonColor))
            Control.BackgroundColor = ((FabButton) Element).ButtonColor.ToUIColor();
        else if(e.PropertyName == nameof(FabButton.ButtonHost)){
            var fabButton = (FabButton)Element;
            if (fabButton.ButtonHost != null && fabButton.ButtonHost.ShouldBeHiddenWhenScrolling)
            {
                fabButton.ButtonHost.LinkedScrollViewScrolled += OnLinkedScrollView_Scrolled;
            }
        }
    }
    

    code-behind ViewModel
    ListView Scrolled