qt视图框架_列表视图框架

本文介绍了Unity Lab为Carte Blanche项目开发的可扩展列表视图框架,旨在创建动态、可滚动的对象列表。该框架遵循MVC和MVVM设计模式,解耦了数据和视图,提高了性能,尤其适用于VR环境。它包含三个核心类:ListViewController、ListViewItem和ListViewItemData。此外,文章还提供了开源代码和示例,鼓励社区成员进行定制和改进。
摘要由CSDN通过智能技术生成

qt视图框架

In order to implement project Carte Blanche’s card system, we developed an extensible framework for creating dynamic, scrollable lists of objects. This article discusses the structure and contents of this framework. The code and sample scenes are available as a Unity Asset Store package and a public repository for the developer community.

为了实施Carte Blanche项目的卡片系统,我们开发了一个可扩展的框架来创建动态的可滚动对象列表。 本文讨论了此框架的结构和内容。 代码和示例场景可作为Unity Asset Store软件包和开发人员社区的公共资源库获得。

Project Carte Blanche (PCB) is Unity Lab’s research initiative on VR-in-VR authoring tools for non-technical users. As illustrated in the concept video, its user interface is based on a playing cards metaphor. Central to the design of Carte Blanche is the idea that objects and actions are represented by virtual cards which users grab and place on a virtual table. The user will physically interact with cards by using tracked motion controllers.

Carte Blanche项目 (PCB)是Unity Lab针对非技术用户的VR-in-VR创作工具的研究计划。 如概念视频所示 ,其用户界面基于扑克牌隐喻。 Carte Blanche设计的核心思想是,对象和动作由用户抓取并放置在虚拟桌子上的虚拟卡表示。 用户将通过使用跟踪的运动控制器与卡片进行物理交互。

PCB’s cards are a more complex version of conventional scrollable lists. List Views are common widgets provided in many GUI toolkits. Unity’s UI system includes several layout components and customizable controls to make dynamic lists which are scrollable and have hover states. A GridLayout or VerticalLayout will get most of the work done, and there’s even a handful of packages on the Asset Store just for lists. However, the existing solutions we found required the lists to be inside of a canvas and exist within the UI system. PCB requires cards to animate in and out of existence and to let the user touch them. Furthermore, performance in VR is critical. One common drawback of “classic” UI list views is that the full list is represented by scene objects which are only masked. If the list structure changes, or perhaps an item is expanded to take up more space, the system must re-evaluate all of the items in the list. We also want to avoid instantiating and destroying scene objects if possible, because this can be costly. Finally, for reusability and consistency of look and feel, we need an extensible solution that allows us to create similar behavior in other UI elements.

PCB卡是传统可滚动列表的更复杂版本。 列表视图是许多GUI工具包中提供的常见窗口小部件。 Unity的UI系统包括多个布局组件和可自定义的控件,以创建可滚动并具有悬停状态的动态列表。 GridLayoutVerticalLayout将完成大部分工作,并且Asset Store上甚至只有一些用于列表 软件包 。 但是,我们发现的现有解决方案要求列表位于画布内部,并且存在于UI系统中。 PCB要求卡片进行动画制作,以使用户能够触摸它们。 此外,VR的性能至关重要。 “经典” UI列表视图的一个常见缺点是,整个列表由仅被遮罩的场景对象表示。 如果列表结构发生变化,或者某个项目可能要扩展以占用更多空间,则系统必须重新评估列表中的所有项目。 我们还希望避免在可能的情况下实例化和销毁场景对象,因为这可能会导致成本高昂。 最后,为了实现可重用性和外观的一致性,我们需要一个可扩展的解决方案,该解决方案允许我们在其他UI元素中创建类似的行为。

Scrollable Lists Beyond the Canvas

We developed a general framework for creating list views, which serves as the foundation of PCB’s card system. Since there are also broad use-cases for such a framework, we decided to release it as an Asset Store package for the community.

我们开发了用于创建列表视图的通用框架,该框架用作PCB卡系统的基础。 由于此类框架也有广泛的用例,因此我们决定将其作为社区的Asset Store软件包发布。

解耦模型和视图 (Decouple Model and View)

One goal of this framework is to follow the MVC and MVVM design patterns, decoupling the logic which displays the underlying data (the view) from the state of the data itself (the model). In any given frame, the framework should automatically handle displaying the current state of the list. This way we only need to take into account the current state of the data without worrying about how to trigger updates to the view. Likewise, we don’t need to worry about synchronization issues when user actions are performed quickly or frames are taking too long to render. As an added bonus, the CPU overhead for the list will stay relatively consistent, since it will be doing the same amount of work all the time. Performance will not degrade significantly when the list size increases or states change in unexpected ways.

该框架的一个目标是遵循MVCMVVM设计模式,将显示基础数据(视图)的逻辑与数据本身(模型)的状态分离。 在任何给定的框架中,框架都应自动处理显示列表的当前状态。 这样,我们只需要考虑数据的当前状态,而不必担心如何触发视图更新。 同样,当快速执行用户操作或帧花费太长时间来渲染时,我们也不必担心同步问题。 另外,列表的CPU开销将保持相对一致,因为它一直在进行相同数量的工作。 当列表大小增加或状态以意外方式更改时,性能不会显着下降。

The idea to represent a list this way is borrowed from the Android and iOS UI frameworks. Both use slightly different implementations, but essentially take the same approach. A container element controls the position of a number of child elements, which are pooled in memory to avoid the cost of allocating and freeing them each time they are scrolled on/off screen. Separately, an interface is defined for how the view gets the information for each list item from the data source. The developer writes code for the data source and designs the list items, and the framework takes care of the rest. Both SDKs provide helpful guides on how to implement a list following the same design pattern of pooling rows and establishing an interface with a data source. iOS calls theirs a UITableView, and Android just calls it a ListView with an associated ListAdapter which talks to the data source.

以这种方式表示列表的想法是从Android和iOS UI框架中借用的。 两者都使用略有不同的实现,但是本质上采用相同的方法。 容器元素控制多个子元素的位置,这些子元素存储在内存中,以避免每次在屏幕上滚动/滚动时分配和释放它们的开销。 单独定义了一个接口,用于视图如何从数据源获取每个列表项的信息。 开发人员为数据源编写代码并设计列表项,其余部分由框架负责。 这两个SDK都提供了有关如何按照池的相同设计模式来实现列表以及建立与数据源的接口的有用 指南 。 iOS将其称为UITableView ,而Android仅将其称为具有关联的ListAdapterListView ,该ListAdapter与数据源通信。

Both implementations set up a framework for laying out scrollable UI elements, and allow developers to define custom functions for how to define what goes on those elements based on rows in a database, lines in a text file, or any data source they desire. The view needs to know the total number of elements in the data set, as well as a method for getting the information to display such as a movie title and rating. Generally there is a default template for just displaying text, but developers can also customize the design of each list row with custom UI layouts. The framework itself takes care of allocating memory for these list rows, and re-using them after they are scrolled offscreen to display upcoming list rows. If each row is using the same template, the system should never have to allocate more than one full-screen’s worth of rows, plus one additional row if the list can scroll smoothly. That last row exists in order to display the first and last row only part-way on screen. We can think of it as having extra “bleed” space at each end of the list.

两种实现都建立了一个用于布置可滚动UI元素的框架,并允许开发人员定义自定义函数,以便根据数据库中的行,文本文件中的行或所需的任何数据源来定义这些元素上的内容。 该视图需要知道数据集中元素的总数,以及用于获取要显示的信息(例如电影标题和评分)的方法。 通常,有一个仅用于显示文本的默认模板,但是开发人员也可以使用自定义UI布局自定义每个列表行的设计。 框架本身负责为这些列表行分配内存,并在将它们滚动到屏幕外以显示即将到来的列表行后重新使用它们。 如果每一行都使用相同的模板,则系统永远不必分配多于一个全屏显示的行,如果列表可以平滑滚动,则再分配一行。 最后一行的存在是为了仅部分显示屏幕上的第一行和最后一行。 我们可以认为它在列表的每个末端都有额外的“出血”空间。

包装 (The Package)

The List View Framework is available as an Asset Store package, as well as an open-source git repository on Unity’s BitBucket account. We hope that this package, and others that we publish in the future, will live on to be used, improved, and re-used by the community. Feel free to fork this repository into your own project with its own fixes or enhancements. The code is released under the MIT/X11 license, which basically means that you can do whatever you want with it as long as you keep the disclaimer. In the future, we at Unity want to release more of our original content as modular open-source packages that can be valuable and improved by the community. This is the first of many modules from Project Carte Blanche which will be released in this way.

List View Framework可以作为Asset Store软件包以及Unity的BitBucket帐户上的开源git存储库提供。 我们希望此程序包以及我们将来发布的其他程序包能够继续为社区所使用,改进和重复使用。 可以使用自己的修复或增强功能将此存储库分叉到您自己的项目中。 该代码是根据MIT / X11许可证发布的,这基本上意味着您只要保留免责声明,就可以使用它进行任何操作。 将来,Unity希望将更多的原始内容发布为模块化的开放源代码软件包,这对于社区来说可能是有价值的并得到改进。 这是Carte Blanche项目众多模块中的第一个,将以这种方式发布。

The framework boils down to three C# classes: ListViewController (split in two), ListViewItem, and ListViewItemData:

该框架可归结为三个C#类: ListViewController (分为两个), ListViewItemListViewItemData

1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public abstract class ListViewControllerBase : MonoBehaviour
{
        public float scrollOffset;
        public GameObject[] templates;
        ...
}
public abstract class ListViewController<DataType, ItemType> : ListViewControllerBase
        where DataType : ListViewItemData
        where ItemType : ListViewItem
{
        public DataType[] data;
        ...
}
public class ListViewItem<DataType> : ListViewItemBase where DataType : ListViewItemData
{
        public DataType data;
        public virtual void Setup(DataType data)
        {
            this.data = data;
            data.item = this;
        }
}
public class ListViewItemData
{
        public string template;
        public MonoBehaviour item;
}

1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public abstract class ListViewControllerBase : MonoBehaviour
{
         public float scrollOffset ;
         public GameObject [ ] templates ;
         . . .
}
public abstract class ListViewController & lt ; DataType , ItemType & gt ; : ListViewControllerBase
         where DataType : ListViewItemData
         where ItemType : ListViewItem
{
         public DataType [ ] data ;
         . . .
}
public class ListViewItem & lt ; DataType & gt ; : ListViewItemBase where DataType : ListViewItemData
{
         public DataType data ;
         public virtual void Setup ( DataType data )
         {
             this . data = data ;
             data . item = this ;
         }
}
public class ListViewItemData
{
         public string template ;
         public MonoBehaviour item ;
}

The reason for splitting ListViewController in two is so that we can access properties which are not dependent on the data type without knowing what implementation of the list we are using. In this way, InputHandler scripts can scroll any kind of list, regardless of what class is actually implementing ListViewController. The framework includes a very basic implementation of ListViewController which accepts items with no data (other than a template) which can be set up in the inspector:

将ListViewController分为两部分的原因是,这样我们就可以访问不依赖于数据类型的属性,而无需知道我们使用的是哪种列表实现。 通过这种方式,InputHandler脚本可以滚动任何类型的列表,而与实际实现ListViewController的类无关。 该框架包括ListViewController的一个非常基本的实现,它接受可以在检查器中设置的没有数据的项目(模板除外):

1

public class ListViewController : ListViewController {}

1

public class ListViewController : ListViewController { }

The simplest possible list (Example 0) uses all of the base classes and just allows the user to scroll a set of objects based on template prefabs and a data array set up in the Inspector. To display meaningful data, users are expected to extend ListViewItemData and ListViewController into classes that describe their particular data, as illustrated in further examples.

最简单的列表(示例0)使用所有基类,并且仅允许用户基于模板预制件和在Inspector中设置的数据数组来滚动一组对象。 为了显示有意义的数据,用户应将ListViewItemData和ListViewController扩展到描述其特定数据的类中,如进一步的示例所示。

Template Setup

The ListViewInputHandler class sets up a base for scrolling or click behavior based on mouse input, for example. And of course, the ListViewScroller sub-class sets up some useful patterns for scrolling behavior. Mouse and Touch input are easy to handle at the same time, but these classes could also conceivably handle gamepad, UI, gestural input or VR devices as well. In the case of PCB , the list views in are manipulated via hand-tracked motion controllers.

例如, ListViewInputHandler类为基于鼠标输入的滚动或单击行为设置了基础。 当然, ListViewScroller子类为滚动行为设置了一些有用的模式。 鼠标和触摸输入易于同时处理,但可以想象这些类也可以处理游戏手柄,UI,手势输入或VR设备。 对于PCB而言,列表视图是通过手动跟踪的运动控制器进行操作的。

结论 (Conclusion)

We hope that this article helps to explain the framework, examples, and how to get started including list views into your next project. Consult the wiki for further reading and an in-depth description of the Core Classes and Examples. Even if you don’t end up using any of this code directly, the concept of decoupling model and view code is a powerful one, and leads to more efficient code that is easy to maintain as your project grows. Game systems often benefit from stateless designs that make very few assumptions, and constantly re-evaluate as much available information as possible, within reason. Our goal was to come up with a system to create a scrollable list that is highly customizable and performs well given a potentially infinite set of data. We now have a robust toolkit of features to support asynchronous caching, non-uniform template sizes, nested data, and complex animation behavior. As should be clear by the diversity of example code, one size does not fit all, and every implementation will have its own caveats, many of which have not been covered.

我们希望本文有助于解释框架,示例以及如何开始使用列表视图进入下一个项目。 请查阅Wiki,以获得进一步的阅读以及对“ 核心类示例”的深入描述。 即使您最终没有直接使用任何代码,去耦模型和视图代码的概念也是强大的,它会导致更高效的代码,并且随着项目的发展易于维护。 游戏系统通常会受益于无状态设计,无状态设计很少进行假设,并在合理范围内不断重新评估尽可能多的可用信息。 我们的目标是提出一个系统,以创建可高度定制的可滚动列表,并在可能存在无限数据集的情况下表现良好。 现在,我们有了功能强大的工具包,以支持异步缓存,不一致的模板大小,嵌套的数据以及复杂的动画行为。 样例代码的多样性应该清楚地表明,一个大小并不能满足所有情况,并且每个实现都有其自己的警告,但其中很多都没有涉及。

The intent with this package is that it becomes property of the community. It was created at Unity, but the source is publicly available on BitBucket, and we encourage users to fork the repo and share their improvements. We can’t wait to see what you come up with!

此软件包的目的是使其成为社区的财产。 它是在Unity上创建的,但源代码可在BitBucket上公开获得,我们鼓励用户分叉存储库并分享他们的改进。 我们迫不及待想看看您的想法!

We’ll leave you with some eye candy:

我们给您留些眼球:

演示地址

Cover image: Timoni West, Unity Labs Principal Designer. Article images: Dennis DeRyke, Unity Graphics Software Development Engineer in Test Matt Schoen & Dio Gonzalez work at Unity Labs; Schoen is a Senior Software Engineer and Dio is a VR Principal Engineer.

封面图片:Unity Labs首席设计师Timoni West。 文章图片:Test Matt Schoen和Dio Gonzalez的 Unity图形软件开发工程师Dennis DeRyke 在Unity Labs工作; Schoen是高级软件工程师,Dio是VR首席工程师。

翻译自: https://blogs.unity3d.com/2016/08/05/list-view-framework/

qt视图框架

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值