?使用 GWT 小部件构建 UI。
在本章中,我们将使用 Material Design 规范为 **TodoList** 应用程序构建一个现代化的 UI。我们将使用 Vaadin gwt-polymer-elements 库,它是 Polymer Paper Elements 集合的包装器。
主屏幕
创建应用程序的 **主屏幕**。
我们将创建一个由 Java 文件(
Main.java
)及其视觉描述符(Main.ui.xml
)组成的 UiBinder 屏幕。您可以通过复制以下代码段或使用 Eclipse GWT 插件生成这些文件。
Main.java
package org.gwtproject.tutorial; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; public class Main extends Composite { interface MainUiBinder extends UiBinder<HTMLPanel, Main> { } private static MainUiBinder ourUiBinder = GWT.create(MainUiBinder.class); public Main() { initWidget(ourUiBinder.createAndBindUi(this)); } }
Main.ui.xml
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'> <g:HTMLPanel> </g:HTMLPanel> </ui:UiBinder>
添加 **菜单项**。
现在,我们可以通过添加菜单项来更新
Main.ui.xml
文件。<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:p='urn:import:com.vaadin.polymer.paper.widget' xmlns:i='urn:import:com.vaadin.polymer.iron.widget'> <g:HTMLPanel> <p:PaperIconItem ui:field="menuClearAll"> <i:IronIcon icon="delete" attributes="item-icon"/> <div>Clear All</div> </p:PaperIconItem> <p:PaperIconItem ui:field="menuClearDone"> <i:IronIcon icon="clear" attributes="item-icon"/> <div>Clear Done</div> </p:PaperIconItem> <p:PaperIconItem ui:field="menuSettings"> <i:IronIcon icon="settings" attributes="item-icon"/> <div>Settings</div> </p:PaperIconItem> <p:PaperIconItem ui:field="menuAbout"> <i:IronIcon icon="help" attributes="item-icon"/> <div>About</div> </p:PaperIconItem> </g:HTMLPanel> </ui:UiBinder>
**注意**:在此步骤中,我们添加了 Paper 和 Iron 包所需的导入。
更新 **入口点** 以使用我们的新屏幕。
package org.gwtproject.tutorial; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.ui.RootPanel; public class TodoList implements EntryPoint { public void onModuleLoad() { RootPanel.get().add(new Main()); } }
运行应用程序。
在浏览器中重新加载页面,您应该看到四个菜单项。您可能会注意到缺少图标。我们将在下一步中修复它。
图标和效果
导入 **图标集合**。
Polymer 附带几个图标集合。在可以使用集合之前,必须先导入它。在此示例中,我们将使用 Iron 集。在下面的代码中,我们使用
Polymer.importHref
实用程序方法,并在集合加载完毕后运行应用程序。package org.gwtproject.tutorial; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.ui.RootPanel; import com.vaadin.polymer.Polymer; import com.vaadin.polymer.elemental.Function; public class TodoList implements EntryPoint { public void onModuleLoad() { // We have to load icon sets before run application Polymer.importHref("iron-icons/iron-icons.html", new Function() { public Object call(Object arg) { // The app is executed when all imports succeed. startApplication(); return null; } }); } private void startApplication() { RootPanel.get().add(new Main()); } }
重新加载应用程序
您现在应该在浏览器中看到所有图标。
添加 **涟漪** 效果
与 UI 元素交互时的反馈通常被认为是积极的。如果您愿意,可以详细了解 Material Design 关于 响应式交互 的理念。
- 将
<p:PaperRipple/>
添加到Main.ui.xml
文件中的每个项目中。 - 我们需要在项目中添加一些 CSS 样式属性,以便涟漪效果限制在项目区域内。
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:p='urn:import:com.vaadin.polymer.paper.widget' xmlns:i='urn:import:com.vaadin.polymer.iron.widget'> <ui:style> paper-icon-item { position: relative; overflow: hidden; } </ui:style> <g:HTMLPanel> <p:PaperIconItem ui:field="menuClearAll"> <i:IronIcon icon="delete" attributes="item-icon"/> <div>Clear All</div> <p:PaperRipple/> </p:PaperIconItem> <p:PaperIconItem ui:field="menuClearDone"> <i:IronIcon icon="clear" attributes="item-icon"/> <div>Clear Done</div> <p:PaperRipple/> </p:PaperIconItem> <p:PaperIconItem ui:field="menuSettings"> <i:IronIcon icon="settings" attributes="item-icon"/> <div>Settings</div> <p:PaperRipple/> </p:PaperIconItem> <p:PaperIconItem ui:field="menuAbout"> <i:IronIcon icon="help" attributes="item-icon"/> <div>About</div> <p:PaperRipple/> </p:PaperIconItem> </g:HTMLPanel> </ui:UiBinder>
- 将
重新加载应用程序以查看涟漪效果。
比较添加
PaperRipple
效果前后点击的反应。
响应式布局
使用
PaperDrawPanel
布局应用程序。Paper 元素集合包括一个响应式抽屉面板。它是一个布局组件,可用于现代应用程序,以确保它们在台式机和移动设备上都能正常运行。有关详细信息,请查看 paper-drawer-panel 的 演示。
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:p='urn:import:com.vaadin.polymer.paper.widget' xmlns:i='urn:import:com.vaadin.polymer.iron.widget'> <ui:style> paper-icon-item { position: relative; overflow: hidden; } </ui:style> <g:HTMLPanel> <p:PaperDrawerPanel ui:field="drawerPanel"> <div drawer=""> <p:PaperHeaderPanel mode="seamed"> <p:PaperToolbar/> <p:PaperIconItem ui:field="menuClearAll"> <i:IronIcon icon="delete" attributes="item-icon"/> <div>Clear All</div> <p:PaperRipple/> </p:PaperIconItem> <p:PaperIconItem ui:field="menuClearDone"> <i:IronIcon icon="clear" attributes="item-icon"/> <div>Clear Done</div> <p:PaperRipple/> </p:PaperIconItem> <p:PaperIconItem ui:field="menuSettings"> <i:IronIcon icon="settings" attributes="item-icon"/> <div>Settings</div> <p:PaperRipple/> </p:PaperIconItem> <p:PaperIconItem ui:field="menuAbout"> <i:IronIcon icon="help" attributes="item-icon"/> <div>About</div> <p:PaperRipple/> </p:PaperIconItem> </p:PaperHeaderPanel> </div> <div main=""> <p:PaperHeaderPanel mode="seamed"> <p:PaperToolbar> <p:PaperIconButton ui:field="menu" icon="more-vert" attributes="paper-drawer-toggle"/> <span>Todo List</span> </p:PaperToolbar> </p:PaperHeaderPanel> </div> </p:PaperDrawerPanel> </g:HTMLPanel> </ui:UiBinder>
添加 *内容面板*
- 添加一个用于存放待办事项的容器。
<g:HTMLPanel> ... <div main=""> <p:PaperHeaderPanel mode="seamed"> <p:PaperToolbar> <p:PaperIconButton ui:field="menu" icon="more-vert" attributes="paper-drawer-toggle"/> <span>Todo List</span> </p:PaperToolbar> <g:HTMLPanel ui:field="content" addStyleNames="vertical center-justified layout" /> </p:PaperHeaderPanel> </div> ... </g:HTMLPanel>
重新加载应用程序
应用程序现在应该具有现代外观并具有响应能力。如果调整浏览器窗口大小,使其宽度小于 640 像素,则抽屉面板应隐藏菜单。
?样式化应用程序
使用 CssResource
样式化
使用 Polymer 小部件时,您可以像往常一样使用 GWT GSS 解析器,并使用 {}
运算符将样式添加到小部件或元素。
更改工具栏的颜色,设置标题文本和内容面板的样式
<ui:style> .toolbar { background: #4285f4 !important; } .header { font-size: 200%; margin-left: 50px; background: #4285f4 !important; } .content { padding: 15px; } ... </ui:style> <g:HTMLPanel> ... <div main=""> <p:PaperHeaderPanel mode="seamed"> <p:PaperToolbar addStyleNames="{style.toolbar}"> <p:PaperIconButton ui:field="menu" icon="more-vert" attributes="paper-drawer-toggle"/> <span class="{style.header}">Todo List</span> </p:PaperToolbar> <g:HTMLPanel ui:field="content" addStyleNames="{style.content} vertical center-justified layout"/> </p:PaperHeaderPanel> </div> ... </g:HTMLPanel>
**注意**:vertical
、center-justified
和 layout
类由 Polymer 提供。
使用 Polymer 样式化
Web Components 使用 Shadow DOM 样式 规则,提供封装的组件样式。此外,Polymer 还提供 Shady DOM,这对于没有实现本地 Shadow DOM 的浏览器来说是必需的。因此,Polymer 会监视并解析每个 <style>
块,并在运行时重写规则。
GSS 处理器以及 GWT 加载 css 资源的方式使得无法使用 shadow
和 polymer
选择器,也无法在 <ui:style>
块中使用 Polymer 属性。因此,您必须在 UiBinder
文件中使用普通的 <style>
。
另一个需要注意的地方是,GWT 会延迟加载 CssResource
,因此,在某些情况下,如果需要在元素位于 DOM 中之前使用样式规则,则必须使用 <style>
。
添加并设置 **浮动操作按钮** 的样式
Material Design 应用程序使用浮动按钮作为主要操作的典型按钮。在 Paper 元素集合中,此按钮称为 paper-fab。
<ui:style> ... </ui:style> <g:HTMLPanel> <style is='custom-style'> .add { position: absolute; bottom: 20px; right: 20px; --paper-fab-background: var(--paper-red-500); } </style> <div main=""> ... <p:PaperFab ui:field="addButton" icon="add" addStyleNames="add"/> </div> </g:HTMLPanel>
**提示**:为了让 Polymer 处理您的样式块,请添加 is="custom-style"
属性。
**提示**:请查看 paper-fab 文档,了解可用的自定义样式属性和混合。
摘要
最后,您的 Main.ui.xml
文件应如下所示
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:p='urn:import:com.vaadin.polymer.paper.widget'
xmlns:i='urn:import:com.vaadin.polymer.iron.widget'>
<ui:style>
paper-icon-item {
position: relative;
overflow: hidden;
}
.toolbar {
background: #4285f4 !important;
}
.header {
font-size: 200%;
margin-left: 50px;
}
.content {
padding: 15px;
}
</ui:style>
<g:HTMLPanel>
<style is='custom-style'>
.add {
position: absolute;
bottom: 20px;
right: 20px;
--paper-fab-background: var(--paper-red-500);
}
</style>
<p:PaperDrawerPanel ui:field="drawerPanel">
<div drawer="">
<p:PaperHeaderPanel mode="seamed">
<p:PaperToolbar addStyleNames="{style.toolbar}"/>
<p:PaperIconItem ui:field="menuClearAll">
<i:IronIcon icon="delete" attributes="item-icon"/>
<div>Clear All</div>
<p:PaperRipple/>
</p:PaperIconItem>
<p:PaperIconItem ui:field="menuClearDone">
<i:IronIcon icon="clear" attributes="item-icon"/>
<div>Clear Done</div>
<p:PaperRipple/>
</p:PaperIconItem>
<p:PaperIconItem ui:field="menuSettings">
<i:IronIcon icon="settings" attributes="item-icon"/>
<div>Settings</div>
<p:PaperRipple/>
</p:PaperIconItem>
<p:PaperIconItem ui:field="menuAbout">
<i:IronIcon icon="help" attributes="item-icon"/>
<div>About</div>
<p:PaperRipple/>
</p:PaperIconItem>
</p:PaperHeaderPanel>
</div>
<div main="">
<p:PaperHeaderPanel mode="seamed">
<p:PaperToolbar addStyleNames="{style.toolbar}">
<p:PaperIconButton ui:field="menu" icon="more-vert"
attributes="paper-drawer-toggle"/>
<span class="{style.header}">Todo List</span>
</p:PaperToolbar>
<g:HTMLPanel ui:field="content"
addStyleNames="{style.content} vertical center-justified layout"/>
</p:PaperHeaderPanel>
<p:PaperFab ui:field="addButton" icon="add"
addStyleNames="add"/>
</div>
</p:PaperDrawerPanel>
</g:HTMLPanel>
</ui:UiBinder>
如果一切正常,重新加载后,您的应用程序应如下所示
下一步
- 我们已经学习了如何使用
UiBinder
创建新的窗口小部件。 - 我们可以将第三方窗口小部件添加到我们的 UI 中。
- 我们了解了导入 Polymer 元素(如图标集合)的机制,以及如何使用提供视觉效果的特殊组件。
- 我们可以使用 Paper 面板创建响应式布局,并且了解了如何在与传统的 GWT 小部件配合使用时使用它们。
- 我们了解了如何在 UiBinder XML 文件中使用 GSS 或 Polymer 解析器设置元素的样式。