Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Mobile Web Apps

使用jQuery Mobile构建原生Android新闻阅读器应用程序:第2部分

by
Difficulty:AdvancedLength:LongLanguages:
This post is part of a series called Use jQuery Mobile to Build a Native Android News Reader App.
Use jQuery Mobile to Build a Native Android News Reader App
Use jQuery Mobile to Build a Native Android News Reader App: Part 3

Chinese (Simplified) (中文(简体)) translation by Xiaxie (you can also view the original English article)

在本系列教程的第1部分中,我们介绍了示例应用程序,描述了页面流,并讨论了如何通过jQuery Mobile在应用程序中构建页面。 在第2部分中,我们将完成Web应用程序的实现。


应用程序启动

在回顾了第1部分中的基本页面结构之后,现在让我们关注在index.html浏览器中加载时会发生什么。 发生该事件时,将显示“类别”页面。我们不想显示空的分类页面,而是想要从用户上次访问(在同一浏览器会话或以前的浏览器会话期间)恢复新闻分类。 因此,每次用户添加新闻类别时,我们都会localStorage使用DST.js插件将其存储在HTML5中,如“存储当前新闻类别”部分所示。 如果用户删除了新闻类别,则会从浏览器的本地存储中删除该类别。 。 当页面在浏览器中加载时,在jQuery中$(document).ready()函数, 我们获取存储的新闻类别并一个接一个地处理它们,为每个新闻类别创建一个列表项。 如下所示。

每个类别由select id="category" ...  类别选择”页面中元素中相应选项的值表示。 当前浏览的类别localStorage以名为键的逗号分隔的类别值的字符串形式存储news。 例如,如果用户当前正在浏览类别“Top Stories”和“Politics”,localStorage则将包含topstories,politics可在名为key的条件下检索的字符串news。 在$(document).ready(), 我们解析存储的类别并创建一个字符串数组,其中每个元素对应一个类别。 然后,我们调用restore()函数:

在中restore(),如果没有要恢复的新闻类别,我们只需显示空的分类页面。 如果有要恢复的新闻类别,我们getNews()通过将该函数传递给列表中的最后一个新闻类别来调用该函数。 请注意,存储的新闻类别构成一个有序列表,其中最新添加的类别是最后一个项目。 因此,我们从最后一个类别开始恢复,以创建先前存储的相同的有序列表。 另一个参数getNews()是函数指针restoreNews。我们将关注两者getNews()及restoreNews()以下。 该getNews()函数构造新闻类别的URL,并对该URL执行jQuery ajax()调用,

. 传递函数指针以处理响应。URL始终以bridge.php? fwd=http://rss.news.yahoo.com/rss/新闻类别开头 ,并将新闻类别作为bridge.php?fwd=http://rss.news.yahoo.com/rss/topstories“热门新闻”类别的最后一段(例如)。 响应是XML格式,我们将很快审核。 响应是XML格式,我们将很快审核。

该函数restoreNews()是AJAX调用的处理程序。 它只是将XML响应转发给另一个名为的函数populateSingleNews()。 然后,它调用前面讨论的restore()函数。 观察到有一系列递归函数调用,如下所示:

变量numNewsToRestore在每次调用中递减一次numNewsToRestore。 递归将继续,直到变量numNewsToRestore到达0。

该文件bridge.php位于同一Web服务器文件夹中index.html,其主要功能是在fwd参数值中对URL执行HTTP GET请求,然后在不进行任何操作的情况下中继响应。 这是针对AJAX请求的同源限制的解决方法。 有关此主题的更多讨论在“转发AJAX请求”中给出。


添加新闻类别

现在让我们看看如何添加新闻类别。 这在populateSingleNews()功能中完成。 该函数的参数是从Yahoo!发送的XML文本。 新闻作为对特定新闻类别的新闻项的AJAX查询的响应。要在我们的应用程序中创建内容,我们只需要一部分XML响应。 下面,我们将展示业务类别的XML响应示例,其中包含该类别下的两个新闻项。 在我们查看代码时,该示例XML将成为基础populateSingleNews()。

title上面的每个元素都对应一个标题。 在中populateSingleNews(),我们将解析XML并添加到列表currentNews中与选定新闻类别相对应的单个列表项。 新闻类别中的新闻标题将通过逐渐淡出一条标题来动画化。

populateSingleNews()从下面开始,分多步完成审查。

获取新闻类别和类别说明

我们级联jQuery find(),first()并且text()用于解析XML中的元素category和description元素。 执行上面的行后,我们有tmpTxt='business'和desc='Business News'。

为新闻类别创建列表项

此时,我们将各种变量设置如下:

接下来,查看下面的HTML片段定义。 由于这些被重复使用,我们在代码中将它们定义为常量。

我们将先前定义的变量与HTML片段组合起来,以动态定义列表项并将其添加到列表中currentNews:

表达方式

翻译成

这为我们提供了与“商业新闻”类别相关联的列表项的完整定义。 注意我们使用jQuery DOM操作方法prependTo()将此列表项添加到currentNews列表中。

上面的这个列表项可以深入了解lijQuery Mobile 中元素的格式和拆分列表构造。 下图显示了动态构造的列表,currentNews其中包含刚刚构建的列表项。 拆分列表项有两个部分。 左边的一个有文本,右边的有一个删除按钮。

Split list item construction

图7.拆分列表项构造。
  • 新闻类别的描述包含在h3标签内,使其成为标题。
  • 注意空p标签id="cat_business"。 通过下面的动画技术,我们将在这些标签中显示新闻标题。
  • 观察标签。 这有助于建立拆分列表。 我们将使用该标签来处理列表右侧的删除按钮。
  • 删除按钮的图标由jQuery Mobile通过设置自动构建data-split-icon="delete"。
  • 该data-split-theme属性为删除按钮定义了jQuery Mobile特定的可视主题。 您可以尝试其中一个a, b, c, d, e,作为该属性的值。 如果留空,jQuery Mobile将分配默认主题。 我们选择d了主题。

此时,我们已经解析了响应XML并动态构造了一个li元素来表示新闻类别。 在剩下的部分中populateSingleNews(),我们需要注意以下事项:

  • 处理新闻类别的删除事件
  • 当用户点击新闻类别时,处理事件以进入新闻页面
  • 动画新闻类别的新闻标题

我们在下面讨论这些问题。

类别删除的事件处理

我们的代码中的以下行定义了a标记的事件处理程序id="cat_business_d"。 当用户按下包含删除图标的拆分列表项的部分时,将调用此方法。

事件处理程序删除列表项,并在一些清理后更新当前新闻类别选择的列表。

  • 回想一下categoryLi='cat_business_d_li'。 我们调用$.doTimeout( categoryLi, false )以终止该类别的新闻项目的动画。 该$.doTimeout()方法是jquery-dotimeout-plugin的一部分。 我们将在“Animate Function”中进一步讨论该插件。
  • 我们使用jQuery的remove()方法找到列表项并从文档中删除。
  • 刚删除新闻类别后,函数调用将storeCurrentNews()刷新HTML5 localStorage以获取当前选择的新闻类别。 该功能在“存储当前新闻类别”中进一步讨论。

去新闻页面

按下包含文本的拆分列表项的部分会将用户带到“新闻”页面,该页面包含新闻类别下所有新闻项的列表。 为了实现这个,我们定义一个事件处理程序如下:

  • 回想一下变量的值categoryA是'cat_business_a'。 因此,事件处理程序在a围绕新闻类别的标签上定义。
  • 我们首先显示进度页面,showProgress()因为我们希望立即通知用户已启动请求。
  • 记住声明category='cat_business'。构造变量使其前4个字符始终'cat_'。 因此,category.substring(4)为我们提供类别标识符,以构建用于获取该类别下的新闻项的URL。 在这种情况下,category.substring(4)='business'。 我们getNews()之前已经过审核。 这一次,它使用不同的处理函数调用populateNewsItems。
  • 我们将在“新闻页面”中查看该功能。 我们将在“新闻页面”中查看该功能。 我们将在“新闻页面”中查看该功能。

动画新闻标题下的类别

最后一段代码populateSingleNews从XML文本中获取单独的新闻标题,并通过淡入/淡出效果在元素中逐个显示它们。

  • 我们在XML文本上级联jQuery find()和each()方法以提取每个新闻项的标题(请注意,该title元素包含新闻标题)。 这些标题放在一个数组中。
  • 回想一下变量的值category是'cat_business'。 最初,通过jQuery的text()函数将数组中的第一个元素设置为元素的内容。
  • 最后,我们调用该animate()方法,向其传递新闻标题数组,元素和表示当前新闻类别的列表项的标识符(categoryLi='cat_business_d_li')

动画功能

该animate()功能的代码清单如下。

  • 函数的输入包括字符串数组,作为动画目标的DOM元素,以及与特定超时函数关联的处理程序。
  • 我们使用jquery-dotimeout-plugin,它提供与JavaScript setTimeout()方法类似但更先进的功能。 我们在动画目标上定义一个内部函数,每2秒执行一次(2000毫秒,定义为变量的值TWO_SECONDS)。 每次执行内部函数时,目标的内容通过淡出/效果替换为文本数组中的下一个项目。
  • 动画将继续,直到$.doTimeout(..., false )被调用传递给它作为第一个参数的句柄。 回想一下前面的讨论,删除新闻类别的事件处理程序包含一个语句$.doTimeout( categoryLi, false ),其中变量categoryLi是传递给animate()相应新闻类别的句柄。 换句话说,在删除新闻类别之前,我们首先停止该新闻类别的动画。

此时,我们已完成对populateSingleNews()功能的审查。


新闻页面

在“走向新闻页面”中,我们谈到了populateNewsItems()。 该函数是当用户按下拆分列表项的文本部分以获取新闻类别时触发的事件处理程序的一部分。 显示进度页面后,事件处理程序调用getNews(),并将其populateNewsItems()作为回调处理程序传入。 显示进度页面后,事件处理程序调用getNews(),并将其populateNewsItems()作为回调处理程序传入。请记住,getNews()对Yahoo!执行AJAX调用 新闻服务器,通过index.php,获取特定新闻类别的新闻项目。 我们以前提供了一个示例XML响应。 我们以前提供了一个示例XML响应。 下面,我们通过提供description两个新闻标题的元素来扩展样本:

第一个description元素的内容相当简单。 它只包含文字。 第二个description元素有一个img标记,用作指向新闻项目的更多细节的链接。

让我们看看populateNewsItems()。

  • 我们item通过级联jQuery find()和each()函数来解析XML文本以查找所有元素。 对于每个item元素,我们然后解析出description子元素,将它包含在p标记之间,在末尾添加水平线,并将结果文本附加到名为的变量tmpTxt。
  • 最后,我们使用jQuery html()函数将内容设置为变量的值tmpTxt。 请记住,这是“新闻”页面的内容部分。

存储当前新闻类别

之前,我们讨论过将当前选择的新闻类别存储在HTML5中,localStorage以便稍后当用户再次访问应用程序时可以恢复它们。
这是完成的storeCurrentNews(),如下所示。

  • 我们使用DST.js插件存储HTML5中的当前新闻类别选择localStorage。 我们首先清理与名为key相关联的存储中的变量news。
  • 然后,我们级联jQuery find()和each()函数来构造一个逗号分隔的新闻类别字符串。 传递给find()方法的内部函数适用于表示新闻类别的列表项。 我们在列表项上级联jQuery find()和attr()函数以提取元素中id属性的值p。 请记住,此id属性的值始终以cat_(例如id='cat_business')开头。 因此,呼叫substring(4)给我们提供新闻类别(例如business)。
  • 新闻类别连接成一个用逗号分隔的字符串。 最后,我们从字符串中删除初始逗号并将其存储在localStorage与名为key的关联中news。

在类别选择页面上添加新闻类别

在类别选择页面上,按“获取类别”按钮将选定的新闻类别添加到类别页面。 按钮事件处理程序的代码buttonGetCategoryVar.click()如下所示:

  • 从第1部分“类别选择页面”中显示的列表中,回想一下“获取类别”按钮,id="buttonGetCategory"以及表示新闻类别id的select元素category。
    如果用户选择了新闻类别,则事件处理程序首先显示进度页面并调用getNews()之前查看的功能。 . 第一个参数getNews()是选定的新闻类别。 第二个参数是回调处理程序addNews()。 如果用户未选择新闻类别,showCategories()则调用(即立即显示“类别”页面)。
  • 回想一下getNews(),该函数进行AJAX调用以获取新闻类别的新闻项。 addNews()当AJAX调用返回时,将调用回调处理程序。 此函数首先调用populateSingleNews()解析XML响应,并在“类别”页面中为所选类别添加新的列表项。 然后,它要求storeCurrentNews()存储当前选择的新闻类别localStorage。 最后,它通过调用显示“类别”页面showCategories()。

其他事件处理程序

我们即将完成Web应用程序的代码审查,只剩下几个事件处理程序。 这些讨论如下:

从类别页面转到类别选择页面

从第1部分“类别页面”中的列表中,回想一下“类别”页面上的“添加”按钮具有:id="buttonAddCategory"。 按钮的事件处理程序如下所示。 它只是调用该showSelect()函数来显示Category Selection页面。 审查showSelect()在第1部分“显示页面”中给出。

从新闻页面转到类别页面

第1部分“新闻页面”中的列表显示了新闻页面的结构。 该页面上有两个后退按钮,一个位于页眉中,id="buttonHdrShowCategories"另一个位于页脚中,id="buttonFtrShowCategories"用户可以返回“类别”页面。这些按钮的相同事件处理程序如下所示。 . 它们只是通过调用显示“类别”页面showCategories(),这在第1部分“显示页面”中进行了审核。

从新闻页面前往新闻详情页面

在先前显示的XML示例中观察到description新闻项的元素可能具有由img标记包围的a标记。 为清楚起见,下面重复此操作:

按下图像会触发从“新闻”页面到“新闻详细信息”页面的转换,将用户带到属性中的URL 。 在新闻详细信息页面上,显示新闻项目的详细信息。 如果description新闻项的元素没有img标签,则新闻项的详细信息将不可用。

从“新闻”页面转换到“新闻详细信息”页面的结果来自常规HTTP GET请求,“新闻详细信息”页面显示在index.html运行“新闻”应用程序的文件之外。 换句话说,window.location变量从属性中index.html的URL 更改(请注意,在本机Android应用程序中,将在本教程系列的第3部分中讨论,从“新闻”页面转换到“新闻详细信息”页面,这是从AJAX调用开始的,而不是常规的HTTP GET。)

从新闻详情页面进入分类页面

当用户按下浏览器上的后退按钮时,会发生从“新闻详细信息”页面到“类别”页面的转换(在许多设备中,这是设备的后退按钮)。 这会再次将window.location变量更改为index.html“类别”页面,并按照“应用程序启动”中所述的步骤显示。


转发AJAX请求

在第1部分“请求/响应模型”中,我们提到通过getNews()使用bridge.php作为中介发送的AJAX请求访问Yahoo!  新闻网址。 这是由于在大多数浏览器中,桌面和移动平台中对AJAX请求的同源限制。 记住如何getNews()构造AJAX URI:

将bridge.php在同一个服务器目录中运行index.html。 实际的新闻URI被传递给参数bridge.php的值fwd。 例如,来自一个AJAX请求index.html被构造如下:bridge.php?fwd=http://rss.news.yahoo.com/rss/business。 因此,bridge.php剥离值fwd并执行HTTP GET请求http://rss.news.yahoo.com/rss/business。 然后,bridge.php将响应发送回index.html。

列表bridge.php如下所示:

实施基于cURL(客户端URL库)。 变量val存储fwd参数的值,这是实际的新闻URL。

  • 我们初始化cURL通过curl_init()并打开一个临时文件命名tmpFile.txt通过fopen()。
  • 然后cURL,我们指示将其输出写入该文件curl_setopt($curlHandle, CURLOPT_FILE, $filePointer)。
  • 接下来的步骤包括HTTP通过curl_exec()和关闭cURL会话来执行呼叫curl_close()。 接下来的步骤包括HTTP通过curl_exec()和关闭cURL会话来执行呼叫curl_close()。此时,cURL会话的响应已写入临时文件。因此,我们通过关闭文件fclose()。 因此,我们通过关闭文件fclose()。
  • 然后我们将文件读入数组,$linesArr = file($tmpFile)其中每一行都在数组的单独条目中。 然后,在foreach()循环中,我们遍历数组并返回响应。

在生产应用程序中,不是将响应写入临时文件,而是将其存储在内存中以获得更好的性能,并避免多个线程尝试写入同一个临时文件。 写入文件在调试方面是有利的。 这样,如果需要检查其详细信息,则始终拥有临时文件的书面副本。 请注意,临时文件将写入到同一文件系统文件夹中,bridge.php并且必须将Web服务器配置为允许将php文件写入文件系统。


iPod Touch和Android设备演示

在下面的图8-10中,示出了在iPod Touch iOS 4.1(左)和Android OS 2.2(右)设备中运行的web应用的并排屏幕图像。 由于屏幕尺寸的不同,外观和感觉以及应用程序的功能特征在两种平台中都非常相似,但有明显例外。

Categories page - iPod Touch

图8.分类页面 - iPod Touch和Android。
Categories page - iPod Touch

图9.类别选择页面 - iPod Touch和Android。
News page - iPod Touch

图10. 新闻页面 - iPod Touch和Android。

Web应用程序文件

我们提供一个名为的档案文件news-web.zip,其中包含Web应用程序的所有文件。 顶级文件夹被命名news。 如果将该文件夹放在Web服务器的根目录下,则可以通过以下方式访问Web应用程序http:///news/index.html。 news-web.zip下面给出文件夹结构和文件的描述。

  • 该news文件夹包含index.html和bridge.php。
  • 该news\css-js文件夹包含使用的cssJavaScript文件index.html。 尤其是:
    • jquery-1.4.4.min.js, jquery.mobile-1.0a2.min.js, jquery.mobile-1.0a2.min.css 是jQuery Mobile框架库。
    • jquery.ba-dotimeout.js是jquery-dotimeout-plugin库。
    • jquery.dst.js是DST.js插件库。
    • news\css-js\images\icons-18-white.png 是jQuery Mobile框架库引用的图像文件。
  • news\img\wait.gif 是进度页面上使用的旋转图标。

需要注意的是我们提供的jquery-1.4.4.min.js, jquery.mobile-1.0a2.min.js, jquery.mobile-1.0a2.min.css,并icons-18-white.png直接从我们的网站服务器。 在css和JavaScript文件在我们的引用index.html文件,如下所示:

另一种选择是jquery-1.4.4.min.js, jquery.mobile-1.0a2.min.js, jquery.mobile-1.0a2.min.css通过官方jQuery Mobile网站在你的html文件中引用如下。

如果您按照另一种方法,jquery-1.4.4.min.js, jquery.mobile-1.0a2.min.js, jquery.mobile-1.0a2.min.css以及icons-18-white.png不需要从你的Web服务器提供。


结束语

在本系列教程的第二部分中,我们完成了Web应用程序的实现。我们主要关注的是动态构建拆分列表,并在拆分列表项中包含文本的动画技术。 在第3部分中,我们将Web应用程序迁移到本机Android应用程序中。 在第3部分中,我们将Web应用程序迁移到本机Android应用程序中。

关注我们的公众号
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.