介绍
早在Android早期,当时还没有良好的用户界面框架,而大多数Android设备的功能却不足,因此创建混合应用程序(使用HTML5,CSS和JavaScript等网络技术开发的应用程序)是一个非常糟糕的主意。
与本地应用程序相比,它们看起来明显不同且性能很差。 但是,那些日子早已一去不复返了。 如今,大多数移动设备都可以轻松运行混合应用程序,并且有许多框架可让您完美地模拟Android的本机外观。 因此,如果您面临的期限很短,或者您的预算很少,那么采用混合方式就不再是一个坏主意了。
在本教程中,我将向您展示如何为Android创建一个简单的混合式待办事项应用程序。 该应用程序的界面将符合Google的材料设计规范,Android Lollipop和Marshmallow的本机外观。 为此,我们将使用Polymer , Polymer纸元素和Apache Cordova 。
先决条件
要继续进行,您将需要:
- 最新版本的Android SDK
- 最新版本的Node.js
- 运行Android 5.0或更高版本的Android设备或模拟器
- 对HTML5,CSS和JavaScript有基本了解
如果你是新的科尔多瓦,然后花点时间阅读本简介由沃纳-贝尔Ancheta。 本简介应该使您快速入门。
1.为什么使用聚合物?
Polymer是一个框架,可让您快速创建自定义Web组件,即Polymer元素。 通过使用Polymer元素,您可以使Web应用程序更具模块化,并使代码更可重用。 创建元素后,就可以像HTML页面中的其他HTML标签一样使用元素。 例如,如果您创建了一个名为my-element的自定义元素,则可以使用以下代码在任何HTML页面中使用它:
此外,通过使用Polymer框架,您可以利用其提供的数据绑定功能使您JavaScript代码更简单,更不易出错。
2.什么是聚合物纸元素?
纸元素是通过遵循材料设计准则而创建的聚合物元素。 它们可以用作常规HTML元素的替代方法。 例如,如果要在页面上添加材质设计按钮,则可以使用paper-button
元素。 这样做的代码如下所示:
Click Me!
同样,如果要添加卡片或浮动操作按钮,则可以使用paper-card
或paper-fab
元素。 我相信您现在已经开始了解聚合物和纸张元素的用途。
3.什么是Apache Cordova?
使用Polymer和Polymer元素创建的应用程序从根本上来说只是HTML,CSS和JavaScript文件的集合。 这意味着它需要浏览器才能运行。 但是,它可以在Web视图内运行,Web视图是一种本机用户界面元素,其行为类似于无镶边浏览器。
Apache Cordova是一个框架,使您可以生成包含Web视图的本机应用程序,并指定要显示HTML页面。 在本教程中,我们将使用Apache Cordova在Android设备上运行待办事项列表应用程序。
4. Web项目设置
为了加快开发速度并简化调试,大多数开发人员开始将其混合应用程序构建为Web应用程序。 我们将做同样的事情。 让我们从将待办事项列表应用程序创建为可以在浏览器中运行的普通Web项目开始。
为项目创建一个新目录,并将其命名为todoWebApp 。
mkdir ~/todoWebApp
为了管理项目的依赖关系,我们将使用Bower 。 如果尚未安装Bower,请使用npm
进行全局安装。
sudo npm install -g bower
安装Bower后,导航至项目目录,并使用bower
命令安装Polymer纸张元素以及必要的依赖项。
cd ~/todoWebApp
bower install PolymerElements/paper-elements
这样就完成了Web项目的设置。
5.创建自定义聚合物元素
现在,让我们创建一个自定义的Polymer元素,其中包含待办事项列表Web应用程序的布局和功能代码。 首先创建一个新文件,并将其命名为task-list.html 。
步骤1:导入纸张元素
自定义元素的布局中使用的每个纸张元素都必须单独导入。 要构建Web应用程序的界面,我们将使用以下元素:
-
paper-toolbar
创建工具栏 -
paper-button
创建各种按钮 -
paper-fab
创建一个浮动按钮 -
paper-listbox
创建包含任务的列表 - 在列表中创建单个任务的
paper-item
-
paper-checkbox
以创建复选框,用户可以选中以将任务标记为已完成 -
paper-icon-button
以绘制具有图标的按钮 -
paper-input
以绘制文本字段,用户可用来输入任务名称 -
paper-dialog
创建模式对话框 -
iron-icons
绘制图标
此外,要使用Polymer提供的数据绑定功能,我们必须导入Polymer框架本身。 将以下代码添加到文件中:
rel="import" href="bower_components/polymer/polymer.html">
rel="import" href="bower_components/paper-toolbar/paper-toolbar.html">
rel="import" href="bower_components/paper-button/paper-button.html">
rel="import" href="bower_components/paper-fab/paper-fab.html">
rel="import" href="bower_components/paper-listbox/paper-listbox.html">
rel="import" href="bower_components/paper-item/paper-item.html">
rel="import" href="bower_components/paper-checkbox/paper-checkbox.html">
rel="import" href="bower_components/paper-icon-button/paper-icon-button.html">
rel="import" href="bower_components/paper-input/paper-input.html">
rel="import" href="bower_components/paper-dialog/paper-dialog.html">
rel="import" href="bower_components/iron-icons/iron-icons.html">
步骤2:建立DOM
您可以将Polymer元素视为HTML页面。 就像HTML页面一样,Polymer元素具有自己的DOM树,其中包含用于用户界面元素的各种标签,用于样式的style
标签以及用于JavaScript代码的script
标签。
要创建DOM,我们必须使用dom-module
标记并将其id
属性设置为元素的名称。 让我们称为自定义元素task-list 。 请注意,名称必须包含连字符。
步骤3:建立版面
使用Polymer元素创建布局就像使用HTML元素创建布局一样简单,只是标签有所不同。 但是,必须确保所有布局详细信息都在template
标记内。
您可以将以下代码添加到dom-module
以创建待办事项列表应用的布局:
My Tasks
{{ item.taskName }}
这可能看起来像很多代码,但是如果您熟悉HTML和车把表达式,就会发现它非常直观。
如您所见,Polymer元素标签可以与HTML标签一起自由使用,并且可以使用内联样式来自定义其外观。
将事件侦听器添加到Polymer元素标签类似于将其添加到HTML标签。 在上面的代码中,我们使用了两种类型的事件侦听器on-click
侦听器可检测on-click
按钮,而on-change
侦听器可检测复选框状态的变化。
您可能还已经注意到,除了Polymer元素和HTML标签之外,我们还使用了dom-repeat
helper template
标签。 如果您还没有猜到它,它就像一个for
语句,可以用来遍历数组的所有项目。 在我们的布局中,它用于绘制属于一系列任务的单个任务。
步骤4:注册元素
在HTML页面中使用自定义Polymer元素之前,我们必须使用Polymer
函数进行注册。 该函数需要一个包含该元素的函数和属性JavaScript对象。 至少,对象必须具有is
属性,用于指定自定义元素的名称。
在template
标记之后添加script
标记,并向其中添加以下代码:
Polymer({
is: 'tasks-list',
// more code goes here
});
步骤5:初始化元素
在元素的布局中,我们在车把表达式中使用了两个属性,即tasks
和latestTaskName
。 但是,该元素还没有那些属性。 要添加和初始化它们,我们必须使用ready
方法。 现在,我们可以简单地将tasks
初始化为一个空数组,而将latestTaskName
tasks
初始化为一个空字符串。
在is
属性之后添加以下代码:
ready: function() {
this.tasks = [];
this.latestTaskName = "";
},
步骤6:存储,更新和删除数据
为了永久存储用户添加到待办事项列表中的任务,我们将通过localStorage
对象使用本地存储。 现在让我们编写一些代码以将任务添加到本地存储中。
该布局已经包含一个paper-dialog
,该paper-dialog
具有一个输入字段,用户可以在其中输入任务的名称。 但是,默认情况下该对话框是关闭的,这不是我们想要的。 在浮动操作按钮on-click
侦听器中,调用对话框的open
方法将其打开。
showAddTaskDialog: function() {
this.$.addTaskDialog.open();
},
借助Polymer的双向数据绑定,用户在对话框的paper-input
都可以在latestTaskName
属性中立即获得。 因此,在对话框的“ 添加”按钮on-click
侦听器内部,我们可以简单地使用setItem
方法将latestTaskName
添加到localStorage
。
localStorage
以键值对的形式存储数据。 为了存储任务,我们将任务名称用作键,并将其是否完成作为值。 由于localStorage
仅适用于字符串(当前不支持布尔值),因此,如果任务已完成,则将存储yes,否则存储no 。
添加任务后,我们可以使用其close
方法关闭对话框。
addTask: function() {
// Store the new task as not completed
localStorage.setItem(this.latestTaskName, 'no');
// Reset latestTaskName
this.latestTaskName="";
// Close the dialog
this.$.addTaskDialog.close();
// Update the list of tasks
this.updateTasks();
},
同样,当用户选中或取消选中与任务关联的复选框时,我们可以通过调用setItem
方法来更新存储在localStorage
对象中的值。 因为我们使用了dom-repeat
助手template
来绘制paper-listbox
的各个项目,所以我们可以使用on-change
事件中存在的model
对象来获取与复选框关联的任务的名称。 另外,我们需要将复选框的checked
状态的布尔值转换为'yes'或'no',然后再将其存储在localStorage
。
toggleTask: function(e) {
// Get the name of the task
var taskName = e.model.item.taskName;
// Convert true/false to yes/no
if(e.model.item.isComplete)
localStorage.setItem(taskName, 'yes');
else
localStorage.setItem(taskName, 'no');
},
如果用户选择删除任务,则可以单击与该任务关联的paper-icon-button
。 要永久删除任务,请在paper-icon-button
on-click
侦听器中调用localStorage
对象的removeItem
方法。
deleteTask: function(e) {
var taskName = e.model.item.taskName;
localStorage.removeItem(taskName);
// Update the list of tasks
this.updateTasks();
},
步骤7:显示任务
您可能已经注意到,在两个电话updateTasks
在两个addTask
和deleteTask
的方法。 在updateTasks
方法中,我们更新tasks
数组(该数组是在ready
方法中初始化的),以反映localStorage
对象的内容。 这是必需的,因为用于显示任务列表的dom-repeat
helper template
仅适用于数组。
在tasks
数组中,我们使用JSON对象表示任务。 每个JSON对象都有两个字段taskName
和isComplete
。 taskName
是一个包含任务名称的字符串, isComplete
是一个布尔值,指示任务是否完成。
为了允许Polymer检测tasks
数组中的更改,而不是使用标准数组函数,我们必须使用Polymer元素中提供的数组操作方法。 现在,我们将使用splice
方法立即从数组中删除所有元素,并使用push
方法将元素添加到数组中。
以下代码创建updateTasks
方法,该方法循环遍历localStorage
对象中的所有项目,并将它们添加到tasks
数组。
updateTasks: function() {
// Empty the array
this.splice('tasks', 0);
// Add items from localStorage
for(var taskName in localStorage) {
var task = {
taskName: taskName,
isComplete: localStorage.getItem(taskName) == 'yes'
};
this.push('tasks', task);
}
},
现在,仅当用户添加或删除任务时, tasks
数组才会更新。 要在打开应用程序后立即显示任务,我们必须在ready
方法内添加对updateTasks
方法的调用。
我们定制的Polymer元素随时可以使用。
6.使用自定义聚合物元素
现在,我们创建一个HTML页面并将自定义元素添加到其中。 创建一个新文件,将其命名为index.html ,并向其中添加HTML head
和body
标签。
在使用元素之前,我们必须添加link
标记以导入task-list.html 。 此外,要删除填充和边距并使用flex布局,请将fullbleed
, layout
和vertical
CSS类添加到body
标签。 因为这些CSS类是由iron-flex-layout
元素定义的,所以我们必须添加一个link
标记以将其导入。
完成上述导入后,我们可以在body
标签内添加tasks-list
标签。 您的文件现在应如下所示:
rel="import" href="bower_components/iron-flex-layout/iron-flex-layout.html">
rel="import" href="./tasks-list.html">
7.在浏览器中运行应用程序
我们的待办事项清单网络应用已准备就绪。 由于Polymer框架需要运行HTTP服务器,因此请在项目目录中使用Python的SimpleHTTPServer
模块启动一个HTTP服务器。
python -m SimpleHTTPServer
您现在可以访问http:// localhost:8000 /来使用您的应用程序。
8. Cordova项目设置
现在我们已经成功地在浏览器中运行了该应用程序,现在该是通过将其嵌入到Cordova项目中将其转换为Android应用程序的时候了。
这意味着我们首先需要使用npm
全局安装Cordova的CLI(命令行界面):
sudo npm install -g cordova
要创建一个新的Cordova项目,我们可以使用cordova create
命令。 作为其参数,它期望应在其中创建Cordova项目的目录的名称 ,应用程序的反向域名标识符以及应用程序的名称。
要将我们的Web项目嵌入Cordova项目中,我们还需要包含一个“ copy-from
选项并指定该Web项目的位置。
以下命令在名为todo的目录中为名为To-do的应用程序创建一个Cordova项目,并包含位于todoWebApp中的Web项目:
cordova create todo com.tutsplus.code.hathi.todoapp "To-do" --copy-from=/home/me/todoWebApp
我们刚刚创建的Cordova项目尚不支持任何平台。 要添加对Android平台的支持,请导航到todo目录并使用cordova platform
命令。
cd todo
cordova platform add android
9.运行混合应用
无需编写任何代码,我们的Cordova项目已经准备就绪。 让我们使用cordova build
命令进行cordova build
。 在继续之前,请确保将ANDROID_HOME
环境变量的值设置为Android SDK的位置。
export ANDROID_HOME=/home/me/Android/Sdk/
cordova build android
如果构建失败,说明无法将名为web-animations.min.js.gz
的文件添加到APK,请尝试删除该文件并重新构建项目。
rm -f ./www/bower_components/web-animations-js/web-animations.min.js.gz
cordova build android
构建成功后,使用cordova run
命令将应用程序部署到Android设备。
cordova run android
现在,您应该可以看到设备上正在运行的应用程序。
结论
在本教程中,您学习了如何使用Polymer和Polymer纸元素创建待办事项列表Web应用程序。 您还学习了如何将Web应用程序嵌入Cordova项目中,以使其在Android设备上作为混合应用程序运行。 即使我们只专注于Android平台,您也可以在iOS设备上运行该应用程序,而无需进行任何代码更改。 要使此工作有效,您需要再次使用cordova platform
命令添加对iOS平台的支持。
要了解如何使用Polymer构建更复杂的界面,请参考Polymer文档 。