我想在我的表单中间覆盖我的ActivityIndicator,但我不完全确定如何解决这个问题,我想我需要在相对布局中包装我的堆栈布局?
我在代码中这样做,我发现的最接近的例子是使用XAML,它使用如下所示的网格:
<ScrollView BackgroundColor="#d3d6db">
<RelativeLayout
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Vertical"
VerticalOptions="FillAndExpand"
Padding="10"
RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}">
<Grid x:Name="SegmentGrid"
RowSpacing="10"
ColumnSpacing="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<WebView BackgroundColor="White" VerticalOptions="FillAndExpand" Source="{Binding DescriptionHtml}" />
</StackLayout>
<ActivityIndicator IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
Color="Black"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=0.33}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=0.33}" />
</RelativeLayout>
</ScrollView>
答案 0 :(得分:23)
如果您对RelativeLayout有问题,您也可以使用在类似上下文中工作的AbsoluteLayout。示例代码如下:
var overlay = new AbsoluteLayout();
var content = new StackLayout();
var loadingIndicator = new ActivityIndicator();
AbsoluteLayout.SetLayoutFlags(content, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(content, new Rectangle(0f, 0f, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
AbsoluteLayout.SetLayoutFlags(loadingIndicator, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(loadingIndicator, new Rectangle(0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
overlay.Children.Add(content);
overlay.Children.Add(loadingIndicator);
如果您想要一个完整的工作示例,我已经提供了一个@ https://github.com/teamtam/xamarin-forms-timesheet
答案 1 :(得分:13)
这是一个可以接受的答案,但我为所有内容页写了一个扩展,并认为它可能很好。
public static void AddProgressDisplay (this ContentPage page)
{
var content = page.Content;
var grid = new Grid();
grid.Children.Add(content);
var gridProgress = new Grid { BackgroundColor = Color.FromHex("#64FFE0B2"), Padding = new Thickness(50) };
gridProgress.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
gridProgress.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
gridProgress.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
gridProgress.SetBinding(VisualElement.IsVisibleProperty, "IsWorking");
var activity = new ActivityIndicator
{
IsEnabled = true,
IsVisible = true,
HorizontalOptions = LayoutOptions.FillAndExpand,
IsRunning = true
};
gridProgress.Children.Add(activity, 0, 1);
grid.Children.Add(gridProgress);
page.Content = grid;
}
备注: IsWorking 必须是ViewModel(已实施 INotifyPropertyChanged )属性的成员。
呼叫扩展页面ctor last statement。
this.AddProgressDisplay();
答案 2 :(得分:7)
您需要使用绝对布局。遵循以下布局层次结构:
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<!--< Your control design goes here >-->
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy}" Padding="12"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
<ActivityIndicator IsRunning="{Binding IsBusy}" Color ="#80000000"/>
<Label Text="Loading..." HorizontalOptions="Center" TextColor="White"/>
</StackLayout>
</AbsoluteLayout>
这样,活动指示符将叠加在堆栈布局的中间。
答案 3 :(得分:6)
是的,您应该将StackLayout包装在Relative Layout中。我已经完成了您给出的示例,并通过将我的XAML格式化为以下代码来实现我的要求
XAML代码
<RelativeLayout ...>
<StackLayout ...>
<ActivityIndicator IsRunning="false"
Color="Maroon"
BackgroundColor="Black"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=0.33}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=0.28}" />
</StackLayout>
</RelativeLayout>
答案 4 :(得分:1)
这里是Nuri YILMAZ版本的可定制版本。
public static void AddProgressDisplay(this ContentPage page, string isVisibleProperty = "IsBusy", string bgColor = "#1a1a1ab2")
{
var content = page.Content;
var grid = new Grid();
grid.Children.Add(content);
var gridProgress = new Grid { BackgroundColor = Color.FromHex(bgColor), Padding = new Thickness(50) };
gridProgress.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
gridProgress.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
gridProgress.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
gridProgress.SetBinding(VisualElement.IsVisibleProperty, isVisibleProperty);
var activity = new ActivityIndicator
{
IsEnabled = true,
IsVisible = true,
HorizontalOptions = LayoutOptions.FillAndExpand,
IsRunning = true
};
gridProgress.Children.Add(activity, 0, 1);
grid.Children.Add(gridProgress);
page.Content = grid;
}
答案 5 :(得分:0)
在代码中你可以试试这个:
RelativeLayout relativeLayout = new RelativeLayout ();
StackLayout stack = new StackLayout ();
ActivityIndicator indicator = new ActivityIndicator ();
relativeLayout.Children.Add (stack);
relativeLayout.Children.Add (indicator);
RelativeLayout.SetBoundsConstraint (stack, () => relativeLayout.Bounds);
RelativeLayout.SetBoundsConstraint (indicator,
BoundsConstraint.FromExpression (() =>
new Rectangle (relativeLayout.Width / 2 - 16, relativeLayout.Height / 2 - 16, 32, 32)));
假设ActivityIndicator的宽度/高度为32/32,您可以选择适合您需要的尺寸或动态计算尺寸。
在RelateiveLayout中似乎仍然存在错误,它偶尔会抛出意外的空指针异常,即使对于可解决的约束
答案 6 :(得分:0)
您还可以在绝对布局中使用活动指示器。并将绝对布局的isVisible属性绑定到isBusy。以下是我的方法
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" AbsoluteLayout.LayoutBounds="1, 1, 1, 1"
BackgroundColor="White" Opacity="0.5" AbsoluteLayout.LayoutFlags="All" x:Name="indicatorFrame" IsVisible="false">
<ActivityIndicator x:Name="indicator" IsVisible="true" IsRunning="true" IsEnabled="true"
HorizontalOptions="Center" VerticalOptions="Center" AbsoluteLayout.LayoutBounds="1, 1, 1, 1"
Color="Black" AbsoluteLayout.LayoutFlags="All" />
</AbsoluteLayout>
cs文件中的绑定看起来像
indicator.BindingContext = this;
indicator.SetBinding(IsVisibleProperty, "IsBusy", BindingMode.OneWay);
indicator.SetBinding(ActivityIndicator.IsRunningProperty, "IsBusy", BindingMode.OneWay);
indicatorFrame.BindingContext = this;
indicatorFrame.SetBinding(IsVisibleProperty, "IsBusy", BindingMode.OneWay);