06 StackLayout & ScrollView

作者: 归零者 分类: Xamarin.forms基础 发布时间: 2017-09-05 15:29


Xamarin.Forms 控件的排版有一些特定的 “规则” 需要使用:

  • AbsoluteLayout
  • Grid
  • RelativeLayout
  • StackLayout


    这一小节先来介绍 StackLayout



    StackLayout

    顾名思义,StackLayout 就像是堆积物品一样,将物件在界面上一件一件叠上去,而 StackLayout 的顺序可以是 从上而下 或 从左到右。

    StackLayout 有两个属性:

  • Orientation,可设定为 Vertical (预设) 或是 Horizontal
  • Spacing of type double,预设值为 6.0

    底下来看代码,這邊自己手动设定一组Tuple<Color, string> 队列,再用循环
    每个对象加入 StackLayout 內:

  1. class ColorLoopPage : ContentPage
  2. {
  3. public ColorLoopPage()
  4. {
  5. var colors = new[]
  6. {
  7. new { value = Color.White, name = “White” },
  8. new { value = Color.Silver, name = “Silver” },
  9. new { value = Color.Gray, name = “Gray” },
  10. new { value = Color.Black, name = “Black” },
  11. new { value = Color.Red, name = “Red” },
  12. new { value = Color.Maroon, name = “Maroon” },
  13. new { value = Color.Yellow, name = “Yellow” },
  14. new { value = Color.Olive, name = “Olive” },
  15. new { value = Color.Lime, name = “Lime” },
  16. new { value = Color.Green, name = “Green” },
  17. new { value = Color.Aqua, name = “Aqua” },
  18. new { value = Color.Teal, name = “Teal” },
  19. new { value = Color.Blue, name = “Blue” },
  20. new { value = Color.Navy, name = “Navy” },
  21. new { value = Color.Pink, name = “Pink” },
  22. new { value = Color.Fuchsia, name = “Fuchsia” },
  23. new { value = Color.Purple, name = “Purple” }
  24. };
  25. StackLayout stackLayout = new StackLayout();
  26. foreach (var color in colors)
  27. {
  28. stackLayout.Children.Add(new Label
  29. {
  30. Text = color.name,
  31. TextColor = color.value,
  32. FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
  33. });
  34. }
  35. Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 5);
  36. Content = stackLayout;
  37. }
  38. }

执行结果:

BUT,会发现 Android 或 WP 有一些 Label 因为数量太多被挤出屏幕外了.

当然你可以试着把字缩或是设定 Spacing = 0 让每个 Label 无间距的靠在一起,这样消失的 Label 就有会有机会出现在屏幕内.

但我门还是将 StackLayout 放到 ScrollView 內,让物件可以上下滑动比较实在.

* StackLayout 的高度会自动调整和內部所有物件加起來的高度一样,所以一般来说我们不会特地对物件设定 VerticalOptions。

ScrollView

书上这里有介紹 typeof 的用法,这边也提一下,因为等等代码会用到.

在 .NET 內,你可以利用 typeof 运算式取得任何类別或是结构 (Structure)。
举例来说,typeof(Color) 就返回一个类为 Type 的 Color结构。

听不懂没关系,总之,你可以用循环配合方法將所有 Color 取出來…

看代码了解一下.

  1. public class ReflectedColorsPage : ContentPage
  2. {
  3. public ReflectedColorsPage()
  4. {
  5. StackLayout stackLayout = new StackLayout();
  6. // Loop through the Color structure fields.
  7. foreach (FieldInfo info in typeof(Color).GetRuntimeFields())
  8. {
  9. // Skip the obsolete (i.e. misspelled) colors.
  10. if (info.GetCustomAttribute<ObsoleteAttribute>() != null)
  11. continue;
  12. if (info.IsPublic &&
  13. info.IsStatic &&
  14. info.FieldType == typeof(Color))
  15. {
  16. stackLayout.Children.Add( CreateColorLabel((Color)info.GetValue(null), info.Name));
  17. }
  18. }
  19. // Loop through the Color structure properties.
  20. foreach (PropertyInfo info in typeof(Color).GetRuntimeProperties())
  21. {
  22. MethodInfo methodInfo = info.GetMethod;
  23. if (methodInfo.IsPublic &&
  24. methodInfo.IsStatic &&
  25. methodInfo.ReturnType == typeof(Color))
  26. {
  27. stackLayout.Children.Add( CreateColorLabel((Color)info.GetValue(null), info.Name));
  28. }
  29. }
  30. Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 5);
  31. // Put the StackLayout in a ScrollView.
  32. Content = new ScrollView
  33. {
  34. Content = stackLayout
  35. };
  36. }
  37. Label CreateColorLabel(Color color, string name)
  38. {
  39. Color backgroundColor = Color.Default;
  40. if (color != Color.Default)
  41. {
  42. // Standard luminance calculation.
  43. double luminance = 0.30 * color.R + 0.59 * color.G + 0.11 * color.B;
  44. backgroundColor = luminance > 0.5 ? Color.Black : Color.White;
  45. }
  46. // Create the Label.
  47. return new Label
  48. {
  49. Text = name,
  50. TextColor = color,
  51. FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
  52. BackgroundColor = backgroundColor
  53. };
  54. }
  55. }


这些代码利用 typeof 将所有 Color 取出后,会利用 CreateColorLabel()产生有顏色的 Label 并逐一塞进 StackLayout 內,再将此 StackLayout 放到 ScrollView。

而这 CreateColorLabel() 方法內会去计算 Label 背景色该是黑色还是白色,让Label 文字更明确。

执行后就能上下滑看看了~

Expand

每个 VisualElement 都能去设定其 VerticalOptions 和 HorizontalOptions,在早一个的章节

其中有四个 LayoutOptions 只读属性可以使用:

  • LayoutOptions.Start
  • LayoutOptions.Center
  • LayoutOptions.End
  • LayoutOptions.Fill (预设)

    像上面 ReflectedColorsPage 代码,可以藉由 Label 黑色的背景观察到, Label 在 StackLayout 左右宽度是 Fill 的。

    这一小节要介绍的是另外四个属性:

  1. LayoutOptions.StartAnd
  2. LayoutOptions.CenterAndExpand
  3. LayoutOptions.EndAndExpand
  4. LayoutOptions.FillAndExpand

*要注意的是,这四个属性只有在 StackLayout 內有效果。

使用时有三个条件限制:

  1. StackLayout 的內容物件总高度不能大于 StackLayout 的高度。
  2. StackLyout 不能设定 VerticalOptions 为 Start、Center 或 End。
  3. StackLayout 內至少有一个子项目的 VerticalOptions设定为 Expand。


完成以上条件就能触发 Expand.而 Expand 的功能就是平均分配物件在 StackLayout 的配置的空间。

底下 Demo 将我们要的 LayoutOptions 取出来后放到 StackLayout 內:

  1. public class VerticalOptionsDemoPage : ContentPage
  2. {
  3. public VerticalOptionsDemoPage()
  4. {
  5. Color[] colors = { Color.Yellow, Color.Blue };
  6. int flipFlopper = 0;
  7. // Create Labels sorted by LayoutAlignment property.
  8. IEnumerable labels =
  9. from field in typeof(LayoutOptions).GetRuntimeFields()
  10. where field.IsPublic && field.IsStatic
  11. orderby ((LayoutOptions)field.GetValue(null)).Alignment
  12. select new Label
  13. {
  14. Text = “VerticalOptions = “ + field.Name,
  15. VerticalOptions = (LayoutOptions)field.GetValue(null),
  16. HorizontalTextAlignment = TextAlignment.Center,
  17. FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
  18. TextColor = colors[flipFlopper],
  19. BackgroundColor = colors[flipFlopper = 1 – flipFlopper]
  20. };
  21. // Transfer to StackLayout.
  22. StackLayout stackLayout = new StackLayout();
  23. foreach (Label label in labels)
  24. {
  25. stackLayout.Children.Add(label);
  26. }
  27. Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
  28. Content = stackLayout;
  29. }
  30. }


执行结果:可以看到四个黃色的 Expand Label 平均在画面上分配的状況。


*最后再提醒一下,Expand 在其他 Layout 是无效的! 只能用在 StackLayout 內!

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

说点什么

avatar
  Subscribe  
提醒
跳至工具栏