按钮与Android上的活动指示器重叠

时间:2019-04-16 10:37:47

标签: xamarin.android

我有一个带有Xamarin表单的Xamarin Android应用程序。我想在按钮的右眼上显示一个ActivityIndi​​cator。到目前为止,我有这段代码可以正常工作:

                <Grid>
                    <Grid.HeightRequest>
                        <OnPlatform x:TypeArguments="x:Double">
                            <On Platform="iOS" Value="39"/>
                            <On Platform="UWP" Value="35"/>
                            <On Platform="Android" Value="48"/>
                        </OnPlatform>
                    </Grid.HeightRequest>

                    <Button Text="{Binding Resources[RestoreBackupLabel]}" 
                        Command="{Binding RestoreCommand}"/>

                    <ActivityIndicator Color="DarkBlue" IsRunning="true" VerticalOptions="CenterAndExpand" HorizontalOptions="End" WidthRequest="40" Margin="0,2,0,2" IsVisible="True" />
                </Grid>

在IOS和UWP上仍然可以使用,但是在Android上,“活动指示器”由按钮覆盖。我必须在这里专门针对android声明订单吗?

1 个答案:

答案 0 :(得分:0)

如果您在此处查看答案,则可以使用现有的控件来完成您要在此处完成的任务

Xamarin Forms button with loading indicator

您需要添加此控件

 public class ButtonWithBusyIndicator : RelativeLayout
{
    public ButtonWithBusyIndicator()
    {
        Children.Add(new Button()
                     , Constraint.Constant(0), Constraint.Constant(0)
                     , Constraint.RelativeToParent((p) => { return p.Width; })
                     , Constraint.RelativeToParent((p) => { return p.Height; }));


        Children.Add(new ActivityIndicator { HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center, HeightRequest = 30, WidthRequest = 30 }
                     , Constraint.RelativeToParent((p) => { return p.Width / 2 - 15; })
                     , Constraint.RelativeToParent((p) => { return p.Height / 2 - 15; }));
    }

    public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(ButtonWithBusyIndicator), string.Empty, propertyChanged: OnTextChanged);
    public static readonly BindableProperty IsBusyProperty = BindableProperty.Create(nameof(IsBusy), typeof(bool), typeof(ButtonWithBusyIndicator), false, propertyChanged: OnIsBusyChanged);
    public static readonly BindableProperty ButtonBgColorProperty = BindableProperty.Create(nameof(ButtonBgColor), typeof(Color), typeof(ButtonWithBusyIndicator), Color.White, propertyChanged: OnButtonBgColorChanged);

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public bool IsBusy
    {
        get { return (bool)GetValue(IsBusyProperty); }
        set { SetValue(IsBusyProperty, value); }
    }

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

    static void OnTextChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = bindable as ButtonWithBusyIndicator;

        if (control == null)
        {
            return;
        }

        SetTextBasedOnBusy(control, control.IsBusy, newValue as string);
    }

    static void OnIsBusyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = bindable as ButtonWithBusyIndicator;

        if (control == null)
        {
            return;
        }

        SetTextBasedOnBusy(control, (bool)newValue, control.Text);
    }

    static void SetTextBasedOnBusy(ButtonWithBusyIndicator control, bool isBusy, string text)
    {
        var activityIndicator = GetActivityIndicator(control);
        var button = GetButton(control);

        if (activityIndicator == null || button == null)
        {
            return;
        }

        activityIndicator.IsVisible = activityIndicator.IsRunning = isBusy;
        button.Text = isBusy ? string.Empty : control.Text;
    }

    static void OnButtonBgColorChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = bindable as ButtonWithBusyIndicator;

        if (control == null)
        {
            return;
        }

        var button = GetButton(control);

        if (button == null)
        {
            return;
        }

        button.BackgroundColor = (Color)newValue;
    }

    static ActivityIndicator GetActivityIndicator(ButtonWithBusyIndicator control)
    {
        return control.Children[1] as ActivityIndicator;
    }

    static Button GetButton(ButtonWithBusyIndicator control)
    {
        return control.Children[0] as Button;
    }
}

并使用

之类的东西
<controls:ButtonWithBusyIndicator VerticalOptions="End" Text="xyz" IsBusy="true" ButtonBgColor="Green" HeightRequest="50" />

如有疑问,请随时还原

祝你好运