【问题标题】:Multi color text in Xamarin Forms ButtonXamarin 表单按钮中的多色文本
【发布时间】:2017-05-27 14:41:28
【问题描述】:

我需要将多色文本作为 xamarin 表单按钮,该按钮针对 IOS、Android 以及未来的 Win 10 应用程序。 Xamarin Forms 按钮控件不支持此功能,需要进行一些自定义。

这是预期的示例按钮图像。

【问题讨论】:

标签: c# button xamarin.forms custom-renderer


【解决方案1】:

您是否尝试过在button 上使用Image 属性?

所以你会得到以下内容:

<Button Text="Text" Image="Tick.png"/>

您可以自己设计(或购买)一个复选标记图形,如 here 所示:

【讨论】:

    【解决方案2】:

    我通常用设计制作一个stacklayout,并使其在后端可点击,如下所示:

    <StackLayout Margin="1" BackgroundColor="Black" Widthrequest="100" HeightRequest="50">
        <Stacklayout BackgroundColor="White" x:Name="yourButtonControl" Widthrequest="100" Orientation="Horizontal" Padding="5" HeightRequest="50">
            <Image Source="your image path" HorizontalOptions="StartAndExpand" />
            <Label HorizontalOptions="End">your text</Label>
        </StackLayout>
    </StackLayout>
    

    使 StackLayout 可点击:

    var tapped = new TapGestureRecognizer();
    tapped.Tapped += clickedEvent;
    yourButtonControl.GestureRecognizers.Add(tapped);
    

    您的活动:

    public void clickedEvent(Object sender, EventArgs e){
    
    }
    

    【讨论】:

    • 它应该具有按钮的外观和感觉。 Stacklayout 没有边框。另外,我需要将它添加到列表视图行中。
    • 您可以通过在另一个带有边距(您希望边框宽度为多少)的堆栈布局内包裹并添加背景颜色以显示边来重新创建边框。
    【解决方案3】:

    您可以为 Button 创建自定义渲染。 iOS 和 Android 都支持带有图像和文本的按钮。 Windows 不支持,这就是为什么它在开箱即用的表单中不受支持。

    请查找 iOS 渲染器示例:

    public class DashboardButtonRenderer : ButtonRenderer
    {
        private const int ImageSize = 25;
    
        private UIButton _button;
        private DashboardButton _dashboardButton;
    
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (e?.OldElement == null && e.NewElement != null)
            {
                _button = Control;
                e.NewElement.BorderRadius = 0;
                _dashboardButton = (DashboardButton)e.NewElement;
                _button.Font = UIFont.SystemFontOfSize((nfloat)_dashboardButton.FontSize, UIFontWeight.Semibold);
            }
        }
    
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (e?.PropertyName == DashboardButton.BadgeCountProperty.PropertyName)
            {
                AddBadgeToButton(_dashboardButton.BadgeCount);
            }
            if (e?.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
            {
                _button.Enabled = _dashboardButton.IsEnabled;
            }            
        }
    
        public override void LayoutSubviews()
        {
            base.LayoutSubviews();
    
            if (string.IsNullOrEmpty(_dashboardButton?.ButtonImage))
            {
                return;
            }
            SetImage();     //Moved from ondraw to handle Device Orientation Change
        }
    
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
            Control.HorizontalAlignment = UIControlContentHorizontalAlignment.Center;
        }
    
        private void SetImage()
        {
            CGSize labelSize = Sizing.GetStringSize(_dashboardButton.Text, (float)_dashboardButton.FontSize, 0f, 0f, UIFontWeight.Semibold);
    
            UIImage image = new UIImage(_dashboardButton.ButtonImage);
            _button.SetTitle(_dashboardButton.Text, UIControlState.Normal);
            image = ImageHelper.ResizeImage(image, ImageSize, ImageSize);
            _button.SetImage(image, UIControlState.Normal);
            _button.TintColor = UIColor.Gray;
    
            var imageAllottedSpaceCenterY = (Control.Frame.Size.Height - _button.TitleLabel.Frame.Size.Height) / 2;
    
            var imageInsetTopBottom = imageAllottedSpaceCenterY - ImageSize / 2;
            var imageInsetLeftRight = Control.Frame.Size.Width / 2 - ImageSize / 2;
    
            var labelInsetBottom = (Control.Frame.Size.Height - ImageSize) / 2 - _button.Frame.Height / 2;
            var labelInsetLeftRight = _button.Frame.Width / 2 - labelSize.Width / 2;
    
            _button.ImageEdgeInsets = new UIEdgeInsets(imageInsetTopBottom, imageInsetLeftRight, imageInsetTopBottom, imageInsetLeftRight);
    
            var labelInsetRight = Device.Idiom != TargetIdiom.Phone ? labelInsetLeftRight + GetLabelLeftOffset(_dashboardButton.Text) : labelInsetLeftRight;
    
            _button.TitleEdgeInsets = new UIEdgeInsets(labelInsetBottom + imageInsetTopBottom + 30
            , labelInsetLeftRight - labelSize.Width / 2 + GetLabelLeftOffset(_dashboardButton.Text)
            , labelInsetBottom, labelInsetRight);
            AddBadgeToButton(_dashboardButton.BadgeCount);
            _button.TintColor = AgvanceColors.TintColor.ToUIColor();
        }        
    }
    

    如果您只需要设置多色按钮的文本,那么您可以使用 iOS 的this 解决方案。

    【讨论】:

    • 能否提供示例工作代码。在这种情况下,我在自定义渲染器方面遇到了挑战。
    • 您的问题是什么?我添加了一个 iOS 示例。
    • 我的挑战是使用 IOS 和 Android 的按钮渲染器来制作多色文本。
    • 您的第一个项目是图像,然后是文本?
    • 这是要求之一。我可以对这些图像使用 FontAwesom 图标,以便将其用作文本。所以,如果我有办法在 Android 和 IOS 的按钮中添加多色文本,我很好。
    【解决方案4】:

    我会选择绝对布局,因为我可以在布局中准确定位我想要的元素。只需在布局顶部添加一个透明按钮,整个布局就像一个按钮

    <AbsoluteLayout HeightRequest="50" WidthRequest="150">
        <Image Source="Check.png"
            AbsoluteLayout.LayoutFlags="All"
            AbsoluteLayout.LayoutBounds="0.1, 0.5, 0.2, 1.0"/>
        <Label Text="TEXT"
            AbsoluteLayout.LayoutFlags="All"
            AbsoluteLayout.LayoutBounds="0.9, 0.5, 0.7, 1.0"/>
        <Button Clicked="ButtonClicked" BackgroundColor="Transparent" BorderWidth="2"
            AbsoluteLayout.LayoutFlags="All"
            AbsoluteLayout.LayoutBounds="0.5, 0.5, 1.0, 1.0"/>
    </AbsoluteLayout>
    

    还有事件

    public void ButtonClicked(Object sender, EventArgs args)
    {
        // do something
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多