1. 引言
下面我们要讲的这个应用是模拟天气预报应用weather.lzx,在该应用中通过ajax来远程请求数据,进行当前天气预报信息的显示。2. 需求分析
2.1 weather.lzx主要显示的是每个城市的天气预报信息,我们可以通过左右切换来查看不同城市的天气信息,由于所有城市的天气信息界面都一样,所以该应用中只包含一个主界面就可以了。在该界面中需要包含天气图片、名称、日期、风力天气状况、温度、空气质量、紫外线强度以及48小时和72小时内的天气状况。2.2 由于天气预报的信息是实时信息,所以在显示当前城市的天气信息时,我们采用ajax技术来进行数据请求。
2.3 每次进行ajax请求数据时,需要有个动画效果来表明当前正在请求过程中。
3. 编码详细讲解。
功能在上面我们已经基本上进行分析了,下面来讲一下具体的代码编写:1.1 定义图片。
由于在该应用中,需要根据天气状况来显示不同的图片,为了便于代码的可读性,我们定义一个resource.lzx,先通过<resource>来引入图片,然后在视图中使用。如
resource.lzx
<library>
<resource name="space" src="images/1px.gif"/>
<resource name="downico">
<frame src="images/tv--jiantou.gif"/>
<frame src="images/tv--jiantou2.gif"/>
</resource>
<resource name="bgimage" src="images/tqyb-background.gif"/>
<resource name="logoimg" >
<frame src="images/01.gif"/><!--暴雨-->
<frame src="images/01.gif"/><!--大雨-->
<frame src="images/01.gif"/><!--中雨-->
<frame src="images/01.gif"/><!--小雨-->
<frame src="images/01.gif"/><!--阵雨-->
<frame src="images/05.gif"/><!--大雪-->
<frame src="images/06.gif"/><!--中雪-->
<frame src="images/07.gif"/><!--小雪-->
<frame src="images/08.gif"/><!--冰雹-->
<frame src="images/1px.gif"/><!--冻雨-->
<frame src="images/10.gif"/><!--雨夹雪-->
<frame src="images/1px.gif"/><!--霜冻-->
<frame src="images/1px.gif"/><!--大风-->
<frame src="images/1px.gif"/><!--沙尘暴-->
<frame src="images/03.gif"/><!--阴-->
<frame src="images/1px.gif"/><!--雾-->
<frame src="images/14.gif"/><!--多云-->
<frame src="images/17.gif"/><!--晴-->
<frame src="images/1px.gif"/><!--晴-->
</resource>
</library>
1.2 Ajax请求数据
同样为了代码的可读性,我们单独建立一个js.lzx,把ajax请求的相关js代码写在该lzx文件中。需要先创建一个js.lzx。因为是模拟城市的天气信息,所以我们先定义一个数组,表示请求该数组内城市的天气信息如:
var cities=["长春","海口","北京","上海","深圳","乌鲁木齐","南昌","香港","澳门","武汉"];
在使用ajax时,需要先创建一个XMLHttpRequest()对象,如:
var ajax=new XMLHttpRequest();
请求某个城市的天气信息时,我们定义了一个request()函数来进行请求:
function request(cityname){
top.show(true);
city.setText(cityname);
ajax.abort();
ajax.onreadystatechange=getResponse;
ajax.open("POST","http://www.openface.org.cn/elooapp/*/weather/Weather?clientflag=abce&action=get3DayForecastByCity&city="+cityname,true);
//ajax.open("POST","http://localhost/070903/stock1.xml",true)
ajax.send(null);
}
在该函数中,参数为当前城市的名称,top.show(true)是使连接状态的界面进行显示,city.setText(cityname)在界面上显示当前请求城市的名称,ajax.abort()是中断之前的ajax请求,因为在左右切换不同城市的天气信息时,可能按键太快,在上次请求信息还没返回前,又进行了新的一次请求。ajax.onreadystatechange=getResponse;每个ajax状态改变时,都会触发这个事件处理器,getResponse为一个函数名。Ajax.open("POST",url)url为请求的url路径,通过ajax.send()方法把请求发送到指定的目标资源,参数为null就可以了。
请求过程中的图片如图:
当ajax状态改变时,都会触发事件处理器,调用getResponse()函数,ajax.readyState ==4时,表示请求完成,ajax.status==200时,表示请求成功。如:
function getResponse(){
if(ajax.readyState==4){
if(ajax.status==200){
parseXML(ajax.responseXML);
}
top.show(false);
}
}
当请求完成时,我们把连接状态设置成false,为不可见。请求成功时,调用parseXML函数来解析返回的数据。
function parseXML(doc){
var node=doc.getElementsByTagName("list");
if(node.length<1) {
myDebug("返回数据结果错误!");
return;
}
else node=node.item(0);
var record=[];
var len=node.childNodes.length;
var tmp;
var t;
for(var i=0;i<len;i++){
if(node.childNodes.item(i).nodeType==1){
t=record.length;
record[t]={};
tmp=node.childNodes.item(i).childNodes;
for(var j=0;j<tmp.length;j++){
var tnode=tmp.item(j);
if(tnode.nodeType==1) record[t][tnode.nodeName]=tnode.firstChild.data;
}
}
}
change(record[0]["icon"],record[0]["condition"],record[0]["low"]+"~"+record[0]["high"],record[0]["windspeed"],record[0]["airquality"],record[0]["ultraviolet"],record[1]["icon"],record[1]["low"]+"~"+record[1]["high"],record[1]["windspeed"],record[2]["icon"],record[2]["low"]+"~"+record[2]["high"],record[2]["windspeed"]);
}
function change(tl,weatherv,imv,windv,airv,lightv,tlogov,timv,twindv,atlogov,atimv,atwindv){
var sArr=["todayLogo","weather","im","wind","air","light","tlogo","tim","twind","atlogo",
"atim","atwind"];
for(var i=0;i<sArr.length;i++){
if(i==0||i==6||i==9){
var number=arguments[i]=="-1"?19:(parseInt(arguments[i])+1)
window[sArr[i]].setResourceNumber(number);
}else{
window[sArr[i]].setText(typeof(arguments[i])=="undefined"?" ":""+arguments[i]);
}
}
}
这段代码是解析返回的数据,并把返回的数据作为参数传给change()函数,change()函数的功能主要是把得到的数据显示到界面上。如图:
1.3 初始化界面(index.lzx)
做完上面的工作以后,来初始化信息界面。

如:
<?xml version="1.0" encoding="utf-8" ?>
<canvas width="240" height="320" debug="false" fontsize="16" font="宋体">
<include href="js.lzx"/>
<include href="resource.lzx"/>
<attribute name="index" type="number" value="0"/>
<view id="bg" width="240" height="320" resource="bgimage">
<text fontsize="22" fgcolor="#FFFFFF" width="100" x="100" y="20" id="apptitle" height="30">天气预报</text>
<view x="6" y="18" width="55" height="70" resource="images/app.gif" id="logo" />
<text id="city" x="70" y="61" text=" " width="120"/>
<view x="150" y="61">
<text name="date" align="left" width="120"/>
<handler name="oninit">
var d=new Date();
this.date.setText(d.getFullYear()+"-"+(d.getMonth()+1)+"-"+d.getDate());
</handler>
</view>
<view id="main" fontsize="16" y="60">
<view id="todayLogo" x="5" y="35" height="60" width="60" resource="logoimg" stretches="both"/>
<view x="70" y="25" height="60" fontsize="18" >
<simplelayout axis="y" spacing="5"/>
<text id="weather" text="多云" width="100"/>
<text id="im" text="30" width="100"/>
</view>
<view x="70" y="75" fontsize="16">
<simplelayout axis="y" spacing="5"/>
<view height="20">
<simplelayout axis="x" spacing="1"/>
<text text="风力:"/>
<text id="wind" width="100" />
</view>
<view height="20">
<simplelayout axis="x" spacing="1"/>
<text text="空气质量:"/>
<text id="air" width="95"/>
</view>
<view height="20">
<simplelayout axis="x" spacing="1"/>
<text text="紫外线强度:" resize="true"/>
<text id="light" width="95" />
</view>
</view>
<drawview y="150" x="5">
<handler name="oninit">
<![CDATA[
for(var i=0;i< 230;i+=4 ){
this.moveTo(i,0);
this.lineTo(i+2,0);
}
this.strokeStyle = 0x66ee99;
this.stroke();
]]>
</handler>
</drawview>
<view name="future" x="5" y="160" height="60" fontsize="15" >
<simplelayout axis="y" spacing="5" inset="5"/>
<view name="tom">
<simplelayout axis="x" spacing="2"/>
<text>48小时</text>
<view id="tlogo" y="-4" resource="logoimg" width="28" height="28" stretches="both" />
<view >
<simplelayout axis="x" spacing="1"/>
<text id="tim" width="60"/>
<text id="twind" width="95" />
</view>
</view>
<view name="afttom">
<simplelayout axis="x" spacing="2"/>
<text>72小时</text>
<view id="atlogo" resource="logoimg" y="-4" width="28" height="28" stretches="both" />
<view>
<simplelayout axis="x" spacing="1"/>
<text id="atim" width="60"/>
<text id="atwind" width="95"/>
</view>
</view>
</view>
</view>
<view id="top" y="135" x="3" visible="false">
<drawview>
<handler name="oninit">
this.strokeStyle=0x9AFF9A;
this.fillStyle=0xBCEE68;
this.lineWidth=1;
this.rect(0,0,232,70);
this.fill();
this.stroke();
</handler>
</drawview>
<view x="30" y="20" width="34" height="34" resource="downico" name="flash" />
<text fontsize="16" fgcolor="green" y="25" x="90" id="downt">连接中...</text>
<method name="show" args="flag">
if(flag){
this.number=false;
this.flashTimer();
}else{
clearTimeout(this.timer);
this.timer=null;
}
this.setVisible(flag);
</method>
<method name="flashTimer">
clearTimeout(this.timer);
this.timer=null;
this.number=!this.number;
alert("sjftest "+this.number)
this.flash.setResourceNumber(this.number?1:2);
this.timer=setTimeout("top.flashTimer()",300);
</method>
</view>
<text x="161" y="293" fgcolor="white" text="退出" height="20"/>
<handler name="oninit">
LzFocus.setFocus(canvas);
canvas.move(0);
</handler>
</view>
<method name="move" args="p">
<![CDATA[
this.index+=p;
if(this.index< 0){
this.index=cities.length-1;
}else if(this.index>cities.length-1){
this.index=0;
}
request(cities[this.index]);
]]>
</method>
<handler name="onkeydown" args="key">
<![CDATA[
switch(key)
{
case 37: //left
case 0x100e:
this.move(-1);
break;
case 39: //right
case 0x100f:
this.move(1);
break;
}
]]>
</handler>
</canvas>
在index.lzx文件中,我们需要通过<include>来分别包含之前定义的js.lzx和resource.lzx,如<include href=”js.lzx”>。id为main的视图主要显示的是天气情况,id为top的视图显示的是连接状态的界面,在该界面中的动画效果是通过两张图片进行切换达到的效果。通过id为bg视图下的oninit事件来触发cities数组中第一个城市的天气信息。
