<p>Xamarin.Forms 绘图规范</p>

创建于 2018-04-13  ·  69评论  ·  资料来源: xamarin/Xamarin.Forms

Xamarin.Forms 绘图规范

主题化

要使 MaterialShell 工作,它不仅需要一个看起来是材料设计的外壳,而且它的所有内容也应该是材料设计。 今天这意味着自定义渲染器。 从用户工作的角度来看,这是繁重且不受欢迎的。 相反,需要一种更好的方法。

简单绘图 API 示例

<Button x:Class="Local.MyButton">
  <Button.Template>
    <DrawingTemplate>
      <Drawing>
        <Grid>
          <RoundedRectangle Background="{x:Bind BackgroundColor}" />
          <Ellipse x:Name="TouchFeedback" Opacity="0" />
          <Text Content="{x:Bind Text}" />
        </Grid>
      </Drawing>
    </DrawingTemplate>
  </Button>
</Button>

至少目前,视图模板必须是DrawingTemplateDrawingTemplate的第一个孩子总是Drawing 。 在Drawing中,您可以使用布局和绘图原语。

绘图原语可以是 x:named 并按名称查找并在后面的代码中进行操作,就像任何其他View一样。 实际上,绘图图元只是一个没有渲染器但必须在Drawing内才能工作的视图。 Drawing仅限于它可以支持的孩子,因为所有的孩子都被折叠成简单的绘图命令。

绘制原始对象可以使用 Brush 类型而不是 Color 类型来提供颜色/背景/等。

使用 MaterialShell 时,所有相关控件都将收到一个默认的Template ,它根据 Material 设计指南对它们进行主题化,并在整个平台上统一它们的外观和感觉。 只需阻止其在资源字典中的传播,即可在层次结构的任何层覆盖此主题。

一旦意识到控件可能不会更改其模板,因为 DrawingTemplated 控件有时可能需要不同的渲染器。

类型

绘图模板

这主要是一种标记类型。 将来我们将取消模板是 DrawingTemplates 的要求。

public class DrawingTemplate : ControlTemplate {}

绘画

一个没有渲染器的视图,而是由其父视图作为本机绘图使用。 绘图是一种非常基本的布局,可以测量,但在布局时始终将其所有子级的大小调整为与自身相同的大小。

public class Drawing : Layout<View> {}

用于在视图中绘图的新 API

public class View : VisualElement // new API only
{
  public ControlTemplate Template { get; set; }

  protected BindableObject GetTemplateChild(string childName);

  protected virtual void OnApplyTemplate ();
}

刷子

public class Brush : BindableObject
{
  public static readonly BindableProperty OpacityProperty;
  public double Opacity { get; set; }
}

纯色画笔

public class SolidColorBrush : Brush
{
  public static readonly BindableProperty ColorProperty;
  public Color Color { get; set; }
}

渐变画笔

public class LinearGradientBrush : Brush
{
  public static readonly BindableProperty GradientStopsProperty;
  [Content]
  public GradientStopCollection GradientStops { get; set; }
}

GradientStopCollection

public sealed class GradientStopCollection : IEnumerable<GradientStop>, IList<GradientStop>

渐变停止

public sealed class GradientStop : BindableObject
{
  public static readonly BindableProperty ColorProperty;
  public Color Color { get; set; }

  public static readonly BindableProperty OffsetProperty;
  public double Offset { get; set; }

  public static readonly BindableProperty StartPointProperty;
  public Point StartPoint { get; set; }

  public static readonly BindableProperty EndPointProperty;
  public Point EndPoint { get; set; }
}

绘制基元

将需要大量具有相关属性的绘图图元。 本文档并不试图定义所有这些,只是注意一些需要存在的明显的。 绘图原语 API 不打算成为 SkiaSharp 的批发替代品。 然而,它的目的是不知道使用 Skia 或用于 paltform 的本机绘图后端。

Skia 的一个好的前进路径是添加一个 SkiaDrawing 元素,该元素将指示通过 Skia 渲染绘图。 然后,Skia 可以渲染所有库存图元,并提供允许编码绘图的 Skia 绘图元素。

形状

namespace Xamarin.Forms.Shapes 
{
  public class Shape : View
  {
    public static readonly BindableProperty FillProperty;
    public Brush Fill { get; set; }

    public static readonly BindableProperty StrokeProperty;
    public Brush Stroke { get; set; }

    public static readonly BindableProperty StrokeThicknessProperty;
    public double StrokeThickness { get; set; }
  }
}

线

namespace Xamarin.Forms.Shapes 
{
  public sealed class Line : Shape
  {
    public Point Start { get; set; }
    public Point End { get; set; }
  }
}

椭圆

namespace Xamarin.Forms.Shapes 
{
  public sealed class Ellipse : Shape
  {
  }
}

文本

public sealed class Text : Shape 
{
  // All the same properties as Label more or less
}

长方形

namespace Xamarin.Forms.Shapes 
{
  public sealed class Rectangle : Shape
  {
    public CornerRadius CornerRadius { get; set; }
  }
}

贝塞尔线

这与 UWP 有很大不同,但是它能够绘制贝塞尔曲线/形状,以及规则的多边形和折线。

namespace Xamarin.Forms.Shapes 
{
  public sealed class BezierLine : Shape
  {
    public IList<BezierPoint> Points { get; }
    public bool ShouldClose { get; set; }
  }
}

贝塞尔点

namespace Xamarin.Forms.Shapes 
{
  public sealed class BezierPoint : Point
  {
    public Size LeftControlOffset { get; set; }
    public Size RightControlOffset { get; set; }
  }
}

去做

  • [x] 添加绘图API
  • [x] 填写刷机API

问题

形状

没有电流是绘制弧线的好方法。 UWP 中执行此操作的机制有点……呃,只是不好玩。

形状当前是视图的事实也有一些要说的。 这是为了确保它们可以被标准布局使用,这很好,因为用户不需要学习新的布局机制。 缺点是绘图原语只能在绘图的上下文中工作,但编译器不会阻止您在绘图的外部使用它们。 反例是使当前似乎是更大的邪恶的绘图特定布局。

理想情况下,布局将允许实现某些 ILayoutable 接口的任何子级,其中视图和绘图基元将实现。 然而,这将是一个突破性的变化,所以目前看来 View 是唯一可行的选择。

刷子

可能需要 ImageBrush。 需要进行研究以确保每个平台都可以在任何使用画笔的地方支持 ImageBrush。

绘图模板

目前核心中不存在根据属性切换渲染器的机制,因为这将需要。 这将需要添加。 理想情况下,这应该比基于模板的开关更通用。

brushes shapes in-progress high impact enhancement ➕

最有用的评论

这必须在 Material Shell 之前发生,因为 Material Shell 依赖于此。 我想你的意思是说你更愿意在壳牌之前看到这个?

壳牌并不专注于更快/更轻松地开始。 它旨在以我们无法将它们作为自己的控件的方式对 Pages 进行现代化改造。 它基本上旨在完全替换它们,我们将鼓励人们考虑移植。 Shell 专注于为最终用户提供更流畅和更丰富的体验,它的动画可以自定义,它可以在动画之前/之后延迟/延迟加载内容,因此它们不会提供打嗝。 它在 Android 中提供了一个 0 GPU 过度绘制内容区域,将其与当前页面进行比较,其中过度绘制只是在图表的“红色去他妈的”部分无处不在。

Shell 不是让人们更快地开始,而是让您的应用程序更快。 例如,使用 Shell,您可以将页面/选项卡/组标记为“频繁”,并且假设用户经常访问它们,它们将被系统保留。 这意味着当您离开并返回时,它们不会重新加载。 我们可以这样做,因为 Shell 拥有整个页面层次结构。

对于如何使用 Shell 优化绘图性能,我们也有一些想法,虽然我们肯定不会将绘图限制在 Shell 上,但可能会使使用 Shell 的绘图效率更高,因为我们可能能够在同一通道中完成所有绘图。 这里需要一粒盐,因为这个尖峰还没有完成,但它在纸上看起来不错。

所有69条评论

@贾斯史密斯

从 XAML 标准化的角度来看,这是一个非常好的想法,并且会提供强大的功能,但是,我会小心地走这条路。 它肯定会有助于将 Xamarin.Forms 移向 XAML 标准 (https://github.com/Microsoft/xaml-standard) 的总体目标。 但是,与 VisualStates 一起,这在现实中会有多大用处存在很大的问号。

必须考虑这些领域的图形加速。 在系统的某些部分(如动画)中,缺乏图形加速已经是一个问题。 我的猜测是,如果 Xamarin.Forms 承担渲染矢量图像的责任,它将随后从底层平台中移除 - 并从 GPU 处理转移到 CPU 处理。 在某些情况下,这将严重影响性能。 不是不应该这样做,而是应该考虑是否可以将处理留在GPU级别而不是移动到CPU。 XF 库的使用者需要了解将在本机平台上运行的内容,以及 XF 库将呈现的内容。

还有原生绘图和跨平台绘图差异之间的平衡问题。 文字是很重要的一点。 文本是否应该在所有平台上呈现相同? 即是否应该将字体渲染传递给 XF 以在所有平台上创建统一性? 可能。 但是,我觉得这不应该是 XF 的整体项目。 人们下意识地检测到小的视觉细节。 细节可能在动画等中。 即使在给定平台上与规范稍有偏差也会让用户感到不舒服。 因此,将所有绘图统一起来并不一定是个好主意。 Avalonia 肯定会走这条路,但这是一个完全不同的案例,这是 Avalonia 和 Xamarin Forms 之间的一个不同点。

此外,还有一条评论是,应注意确保任何基本类型的名称相同,并尽可能与 UWP 和 WPF 等其他平台对齐,以符合 XAML 标准。

@davitortinau ,你对此有什么想法吗?

材料设计的一大特色是波纹。 你希望支持这个吗?
总的来说,我认为这太棒了!

我真的很喜欢这个方向。 对于 iOS,我使用原生元素(i,> 选项)使用原生视图单元格,但是我应用自定义主题的次数越多,我发现自己只是在模仿一些原生单元格,并且更多地使用流利的外观/工作主题与应用程序一致,但除细节外本身不是原生的。 我认为如果使用适当的底层渲染库GPU不会有问题,请阅读Skia。 同样的事情也为 Flutter 提供动力。

也许这是一个单独的问题,但同时让 SVG 成为 Forms 的一等公民会很好。 例如,在按下图像按钮时启用简洁的效果,例如动画着色。

我的观点是,最终你想要功能强大、丰富、具有原生外观(不是原生!)的控件,这些控件易于编程,具有跨平台的一致行为,但有一个奇怪的例外是要适应平台的原生怪癖。 例如,Android 的涟漪效应。

@ChaseFlorell事实上我是这样做的。 这个想法是您可以 x:Name 模板中的内容,然后使用 FindByName 将它们挖掘出来。 一旦你有了原生元素,你就可以像其他任何东西一样应用动画,但是可能会有一种特殊的方法来获取动画回调。 我仍在研究这些确切的细节。 使用 Skia 进行绘制,这可以轻松在 android 上达到 60FPS,即使没有 Skia,您也可以在其他平台上达到 60FPS。

@rogihee SVG 真的不是一种运输格式,抱歉:/我不想负责尝试一致地跨平台呈现 SVG。 他们什么时候会向SVG添加提示......

@jassmith ,这将是我们的硬件图形加速吗?

来自 Qt 的 QML,很想看到这个。 结合一些明显的内置控件,可以转换很多地面。

也许有点为时过早或值得另一个问题,但是基于此构建的控件的可访问性/可测试性故事计划是什么?

@RichiCoder1 a11y 肯定需要妥善解决。 理想情况下,Text 元素会自动设置简单控件所需的大部分属性。

这是 xf 4.0 的功能吗?

3.0系列

@jassmith路线图中没有关于 draw 和 shell 的内容

AFAIK 公共路线图不包括任何尚未完全安排的内容

2018年所有这些都会预览吗?@jassmith

@juepiezhongren我们没有承诺做这些提议。 在这里展示它们是为了公开讨论它们的优点、不足等。

我从您的兴趣中得知这些规格对您来说很有趣。 您能否分享一些具体示例,说明在使用 Xamarin.Forms 构建应用程序时您看到它们在哪些方面为您提供帮助? 您认为这解决了哪些问题? 你认为他们为你打开了哪些机会?

您可以分享的任何真实示例和故事都将非常有用,可以帮助我们验证这是否可以提供真正的价值。

与往常一样,如果愿意,任何人都可以随时给我发电子邮件。 大卫。 [email protected]

对我来说最大的问题是“我们不能用 Forms 框架做到这一点”,我必须给潜在客户和 UX/UI 的答复。 它抹黑了这个框架,我只有这么多的机会与客户打交道。

形式缺乏我们公关的组合范式。 项目可以使用 UI 原语构建 UI。 这适用于导航、动画(包括英雄动画之类的东西)、UI 元素和手势。

这个建议会给我们这种平台中立的组合 UI 原语吗?

@timahrentlov我们需要讨论并确切了解这些限制是什么以及这些限制的原因。 但老实说,我什至不敢想或看那么远。 我在 Xamarin Forms 中看到的问题是从一个更简单的角度来看:它仍然是一个开发资源非常有限的项目。 讨论它可以做什么是不切实际或无用的,而实际上并没有足够的动力和燃料。 我不明白这一点。 也许 Xamarin 仍然暗中希望 OSS 社区的一些人能够开始工作和修复问题? 不要误会我的意思,我尊重 Xamarin 在 Xamarin Forms 中投入的时间和精力。

@davidortinau
跨平台很难做出独特的视觉设计,独特的按钮外观,独特的占位符消失效果等r真正避免我们的应用程序相同。 比如mac的通知淡化,轻微的爆炸,很容易给客户留下深刻印象。 为什么我们那天非常喜欢 wpf,我要提到的一个原因是控制模板,我们非常喜欢路径,因为我们的独特性,比如角形六边形按钮。 我们希望 xf 将这些带给跨平台客户端开发人员。

@juepiezhongren如果您正在寻找那种 UI 定制,我认为没有任何跨平台框架可以做到这一点。 关于 WPF:将 WPF 与移动设备混合使用是个坏主意。

我的团队也在使用 React Native,很多 jser 贡献了很多,3 个月后我们得出结论,它根本没有生产力。 对于 xf,它有缺点,有 bug,但基本上它是可靠的解决方案,eps x.native 使所有原生 api 都有效。 所缺少的只是普遍的外观,cusidering flutter' 最近的疯狂。 另外,有了shell,flutter就没有用了,没有flutter.ios之类的东西,flutter就像rn一样,原生api无限痛苦。

@opcodewriter
我们比较频繁地使用skiasharp,进行特殊控制,它的性能令人满意

@jassmith你考虑过使用webgl将materialShell移植到wasm,对于skia,也许它太大而无法下载

正确,我们不想对默认绘图 API 的任何第三方库进行硬性开发。 \可以那样做

在 wasm 中使用 xamarin.mono 和 shell,任何 alpha 产品都将在中国引起 dotnet 复兴,在中国,对 dotnet 的仇恨太盛行了

@jassmith关于这个问题有什么好消息吗?

你在找什么消息@juepiezhongren? 在这一点上,它是为了引发讨论而发布的规范。

我们想看看何时将 draw 和 shell 包含在路线图中@ChaseFlorell
通用渲染已经对 avalonia 和颤振有效

这方面的时间表将取决于我个人的发展速度。 这里的目标不是分散整个团队的注意力,只是让我参与其中。 如果你想观察它的组合,你可以跟踪 shell 分支。 之后壳牌会来绘图。

作为说明,我打算非常快速地竖起一个垂直的绘图切片,然后请求社区提供帮助,如果他们想更快地完成它。

这一切都很好,但它会使用图形加速吗?

@jassmith在 ios 上,使用 system.draw; 在android上,要使用skiasharp || 每件事都滑雪?

@juepiezhongren它将支持多个后端,因此如果您希望它使用 Skia,它将使用 Skia,如果您希望它使用本机绘图 API,它将使用它。 默认情况下,它将使用本机后端,并且 Skia 将选择加入,因此不会强加于您。

@jassmith确实很清楚 system.draw 可用于 ios 而不适用于 android

@juepiezhongren添加对 System.Drawing 的支持不在我的权限范围内。 但是,此规范不会使用 System.Drawing。

基本上,draw 会导致更少的渲染

不是真的,图纸必须得到渲染它们的东西的支持。 除非您的意思是减少对自定义渲染器的需求,否则我同意。

我在“尽可能靠近 wpf/uwp”阵营,我知道这并不总是这里最受欢迎的位置。

但是,这似乎是在执行所有渲染的框架和当前的 XF 范例之间完全没有视觉效果之间的一个很好的折衷。

我假设原语在每个平台上都有对应的,因此硬件加速不会成为问题。 Windows/iOS/Android/etc 仍在渲染矩形、圆形、渐变等,并将使用硬件加速到他们已经使用的相同程度。 这只会让我们的控件设计人员能够使用原语来设计我们的控件,而不是拘泥于 Apple 的按钮理念与 Microsoft 的理念。

我总结得对吗?

@pmoorelegistek基本上就是这个想法。 我们首先处理材质,主要是因为它没有将模糊作为主要设计元素。 这意味着我们实际上可以让它在任何地方工作(看看你的 Android)。

当我完成 Shell v1 后,我将立即移至此

@jassmith这是金。 在适合 UX 设计的地方使用本机控件,并轻松地仅为需要的(最好是少数)设计元素添加类似滑雪的绘制控件。

不再与设计师和客户进行“在 Xamarin Forms 中无法做到这一点”的对话。 这消除了设计限制,同时保留了真正的原生感觉(与颤动不同)。

我很想在材料外壳之前看到这个。 这解决了 XF 的实际限制。
Shell 是第 n 个用于轻松/快速入门的功能。 获得_started_ 一直是焦点太久了,但是像这样让_further_ 获得的功能将_keep_ XF 开发人员加入。

这必须在 Material Shell 之前发生,因为 Material Shell 依赖于此。 我想你的意思是说你更愿意在壳牌之前看到这个?

壳牌并不专注于更快/更轻松地开始。 它旨在以我们无法将它们作为自己的控件的方式对 Pages 进行现代化改造。 它基本上旨在完全替换它们,我们将鼓励人们考虑移植。 Shell 专注于为最终用户提供更流畅和更丰富的体验,它的动画可以自定义,它可以在动画之前/之后延迟/延迟加载内容,因此它们不会提供打嗝。 它在 Android 中提供了一个 0 GPU 过度绘制内容区域,将其与当前页面进行比较,其中过度绘制只是在图表的“红色去他妈的”部分无处不在。

Shell 不是让人们更快地开始,而是让您的应用程序更快。 例如,使用 Shell,您可以将页面/选项卡/组标记为“频繁”,并且假设用户经常访问它们,它们将被系统保留。 这意味着当您离开并返回时,它们不会重新加载。 我们可以这样做,因为 Shell 拥有整个页面层次结构。

对于如何使用 Shell 优化绘图性能,我们也有一些想法,虽然我们肯定不会将绘图限制在 Shell 上,但可能会使使用 Shell 的绘图效率更高,因为我们可能能够在同一通道中完成所有绘图。 这里需要一粒盐,因为这个尖峰还没有完成,但它在纸上看起来不错。

@weitzhandler我希望在接下来的 4 到 6 周内转向这个。 这将更快地开始工作该外壳。 这些时代都不是一成不变的。

+1

@jassmith https://github.com/nventive/Uno
这太棒了。
单色渲染很棒

forms 将成为激进的探索者,而 uno 将成为保守的探索者
我们都爱

+1 很棒的功能,它将解决我们希望尽快看到的许多自定义 UI 问题

@jassmith好像要在 3.3.0 上做draw?

这事有进一步更新吗?

对我们来说,这是我们希望 Xamarin 实现的最引人注目的功能。

我们主要开发 LoB 应用程序,我们的首要任务之一是开发速度。
我们不太关心原生的外观和感觉,只要有一个引人注目的 UI 做得不错,渲染得很好,并且需要更少的开发时间。

必须在每个平台上分别测试和调整每个表单和页面,这是一个实时杀手,需要在所有平台上来回检查任何细微的 UI 更改。

Shell & Material 贝壳是福,也是好消息,请推动这个! 这是唯一能让您的用户继续前往其他地方(Uno、Flutter 和其他)的东西。

3.3 不会出现平局的不幸消息

为此+1,来自uwp背景,我真的很想使用XF,但它有缺点,目前我正在尝试颤动,但如果尽快实施,肯定会使用XF。

我同意这是一个很棒的功能,必须实施。我还将包括线条的样式,例如实线、虚线等...

任何新闻? 计划? 路线图?

有趣的是,就在昨晚,我发现自己正在尝试自定义渲染器,并且几乎得出结论,所有这一切都可以通过将我们自己的原语定义为自定义视图并构建它们来完成。 您只需要边框、椭圆和线即可。
我很想看到这个官方支持,但我不等。 :)

@jassmith
那么例如LineRectangle将是一个真实的视图吗? (因为在示例中我看到有一个GridEllipse作为子视图)。 将要
我能否将 TapGestureRecognizer 添加到Rectangle以处理点击事件?
既然这些是真实的视图,那么绘制图元的实际视图不会不利于渲染速度吗?

@andreinitescu我相信他们的意图是让它们成为 Xamarin Forms 方面的真实视图,但永远不会被原生地实现为视图:

_一个绘图原语只是一个没有渲染器的视图_

因此,更上一层的渲染器( Drawing ? DrawingTemplate ?)负责遍历可绘制的后代并绘制它们。

我猜这意味着适用于设置了CompressedLayout.IsHeadless的布局的相同类型的限制将适用(没有手势识别器、没有效果、没有变换等)

@GalaxiaGuy我的想法是一样的,但我发现它有点令人困惑,因为它与像网格这样的真实视图混合在一起。 真的有必要吗? 而不是从 View 派生,为什么不将这些作为抽象绘图元素(也许有一个名为DrawingElement的基本抽象类,具有公共属性?)

好工作只是正确的样本

<Button x:Class="Local.MyButton">
  <Button.Template>
    <DrawingTemplate>
      <Drawing>
        <Grid>
          <RoundedRectangle Background="{x:Bind BackgroundColor}" />
          <Ellipse x:Name="TouchFeedback" Opacity="0" />
          <Text Content="{x:Bind Text}" />
        </Grid>
      </Drawing>
    </DrawingTemplate>
  </Button.Template> --> correct this line
</Button>

也许它会在 4.0 中?

Drawing很好,因为它使用独立于目标平台的图形基元来实现控制。 曾经有 NControl,但这有问题(从 netstandard2.0 之前,SkiaSharp 之前的日子开始),并且没有更新。

规范 1. 复制了已在 SkiaSharp 中以更完整的形式实现的功能,2. 通过 XAML/Binding 添加了不必要的复杂层,该层位于已经无法维护的 Xamarin.Forms 存储库中。

更好的方法是制作一个基于 SkiaSharp 的小型控件库。 NControl++

@jassmith @rogihee SVG 真的不是一种运输格式,抱歉:/我不想负责尝试始终如一地跨平台渲染 SVG。

SkiaSharp 支持 SVG。

有这方面的消息吗?

有这方面的消息吗?

还想知道这是否仍然可能发生。 我非常想要一个看起来不美观的跨平台 UI 框架,这似乎是实现这一目标的最佳方式。

@legistek您可以使用 SkiaSharp 进行无外观的跨平台绘图。 在您看来,特定于 Xamarin.Forms 的优势是什么?

UI 框架除了绘图之外还有更多内容。

但是这个线程正在讨论绘图框架而不是 UI 框架......

我以为它是在讨论 _for Xamarin Forms_ 的绘图框架。

SkiaSharp 是 Xamarin Forms 的绘图框架。 它也适用于其他 .Net UI 平台这一事实无疑是优势而非劣势。

正如 OP 中所说,SkiaSharp 很可能是各个平台上的底层绘图引擎,但该提案的想法是添加一个抽象层并支持通过 XAML 进行绘图,其中最显着的是数据绑定。 你所说的不必要的复杂性,我称之为优雅。

这还活着和/或它会被卷入 MAUI 吗?

@legistek https://github.com/xamarin/Xamarin.Forms/wiki/Feature-Roadmap列出了 Xamarin.Forms 4.7.0 路线图上的形状、路径和画笔。

好消息! 谢谢!

此页面是否有帮助?
0 / 5 - 0 等级