码迷,mamicode.com
首页 > 其他好文 > 详细

使用NGUI制作关联下拉菜单(查询全国天气)

时间:2015-10-16 00:54:42      阅读:338      评论:0      收藏:0      [点我收藏+]

标签:

关联菜单,在我们浏览网页时经常见到,它极大的方便了我们的操作,在游戏中,偶尔也会用到关联下拉菜单。下面,我们使用关联下拉菜单来查询下全国的天气。
首先,老规矩我们搭建基本的UI界面。我们就不自己去制作UI组件了,直接使用NGUI封装好的UI组件。
  1. 我们先创建于一个Sprite,重命名为BgSprite,为其选择图集和精灵。
  2. 在菜单中选择NGUI,选择Open,打开Prefab Toolbar,拖一个PopupList,重命名为ProvincePopupList。这里,我们要注意, 我们导入支持中文的字体,不然我们输入中文,在下拉菜单中无法显示。
  3. 导入动态字体,Window用户可以在控制面板\外观和个性化\字体中选择一个中文字体,然后将其拖放到桌面,回到Unity中,创建一个文件夹,命名为Fonts,将刚才的字体导入。Mac用户,请自行百度。当然你还可以从其他资源中导入你喜欢的字体。
  4. 导入完字体后,我们选中ProvincePopupList在UI PopupList组件中修改字体,为你刚才导入的字体。我这里是这样的,技术分享,删除Options中的内容,然后展开ProvincePopupList,修改其子物体Label的字体,也为我们刚才的字体,然后再Text属性栏中,输入”省份“。然后,选中ProvincePopupList,Ctrl+D复制两个。调整三者的位置。然后分别命名为 “City Popup List”和“DistrictPopup List”,然后 分别修改Label为“城市”,“区县”。
  5. 最后,我们创建一个Label,用来显示我们查询到的信息。我这边比较简单的显示下结果,当然,你还可以花点心思设计下展示天气页面,我这边就不设计了,直接创建一个Label来显示。创建一个Label,重命名为Show Label,为其选择我们刚导入的字体。
好了,基本的UI界面搭建完成了,下面我们来编写脚本。在写脚本之前,我们需要去聚合数据,注册一个账号,我们将从这里请求数据。网址是,https://www.juhe.cn/
登陆后,我们在首页找到全国天气预报,点击进入,会提示我们申请数据,我们点击申请数据,进入后,我们按照提示,如果是第一次注册,需要先实名认证,等待审核通过后,我们就可以申请数据了。提醒,天气预报的免费次数只有500次,省着点用啊。申请成功后,我们看看需要注意看下这个数据支持的格式,目前支持的是Json和Xml,它下面还有示例,我们可以看看。由于,我们需要请求的数据是Json格式的,所以,我们导入Unity支持的Json动态链接库文件(dll扩展名),LitJson.dll ,没有的童鞋,我会在文末给出网盘链接,当然你也可以找度娘。
我们回到Unity中,创建一个文件夹,Plugins,它是Unity默认的文件,用来存放我们的 插件等文件。我们找到我们的LitJson.dll文件,将其导入到Plugings文件下。
好了,我们来开始编写脚本,我们创建一个C#脚本,命名为Global,它将作为我们的静态或者常量的工具类,打开脚本,首先,它不需要继承MonoBehaviour,我们创建两个公共静态字符串变量,用来存放我们的网址。脚本如下:
技术分享
using UnityEngine;
using System.Collections;

public class Global  {
    public static string areaUrl = "http://v.juhe.cn/weather/citys";     //支持的城市 ,在聚合数据/天气预报的第6条
    public static string weatherUrl = "http://v.juhe.cn/weather/index";  //更加城市名或id查询天气 ,在聚合数据/天气预报的第1条
    public static string appKey = "您申请的AppKey";   //申请是appkey
}
Global

 

保存,回到Unity中,我们在创建一个脚本。命名为Weather。这个脚本中,我们将开启两个协程,一个用来请求区域信息,一个用来请求天气信息。代码如下:

技术分享
using UnityEngine;
using System.Collections;
using LitJson;      //引入 LitJson

public class Weather : MonoBehaviour {
    public UIPopupList provincePopupList;  //省份
    public UILabel provinceLable;        //显示省份的label
    public UIPopupList cityPopupList;   //城市
    public UILabel cityLable;          //显示城市的label
    public UIPopupList districtPopupList;  //区/县
    public UILabel districtLable;     //显示区/县的label
    public UILabel lable;    //显示结果的label

    private JsonData resultData;   //请求到的城市数据

    void Start()
    {
        provincePopupList.Clear();     //清空省份list
        StartCoroutine(RequestData());  //开启协程开请求区域数据
    }

    //选择城市,当我们的省份的provincePopupList的值发生变化时,我们调用这个方法,来更新城市
    public void SelectCity()      
    {
        cityPopupList.Clear();    //情况城市List
        for (int i = 0; i < resultData.Count; i++)
        {
            //遍历区域数据,找到省份List上的省份
            if (resultData[i]["province"].ToString().Equals(provinceLable.text))
            {
                //不存在这个城市,加到城市List上
                if (!cityPopupList.items.Contains(resultData[i]["city"].ToString()))
                    cityPopupList.AddItem(resultData[i]["city"].ToString());
            }
        }
    }
    //选择曲线,当我们的省份的cityPopupList的值发生变化时,我们调用这个方法,来更新区县
    public void SelectDistrict()
    {
        districtPopupList.Clear();  //清空曲线List
        for (int i = 0; i < resultData.Count; i++)
        {
            //遍历区域数据,找到城市List上的城市
            if (resultData[i]["city"].ToString().Equals(cityLable.text))
            {
                //不存在这个区县,加到区县List上
                if (!districtPopupList.items.Contains(resultData[i]["district"].ToString()))
                    districtPopupList.AddItem(resultData[i]["district"].ToString());
            }
        }
    }

    //展示天气
    public void ShowWeather()
    {
        //拼接请求城市的Url
        Global.weatherUrl = Global.weatherUrl + "?format=2&cityname=" + GetUTF8(districtLable.text) + "&key=" + Global.appKey;
        StartCoroutine(RequestWeatherData(Global.weatherUrl));   //开启协程来查询天气数据
    }
    //将字符串转换成UTF8编码,因为根据城市名称来请求数据是,需要传入的城市名为UTF8编码格式的
    private string GetUTF8(string str)
    {
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str); 
        return System.Text.Encoding.UTF8.GetString(buffer);
    }
    //协程,用来请求区域数据
    IEnumerator RequestData()
    {
        WWW www = new WWW(Global.areaUrl + "?key="+ Global.appKey);      //拼接请求区域URL
        while (!www.isDone)
        {
            //没有完成
            yield return null;
        }
        if (www.error == null)     //没有错误
        {
            JsonData data = JsonMapper.ToObject(www.text);   //将请求到的Json 数据转换成 JsonData对象
            resultData = data["result"];  //将结果,赋值给我们的resultData ,因为后面还要用到这个数据来刷新城市和区县
            for (int i = 0; i < resultData.Count; i++)
            {   
                //遍历区域数据,如果没有这个省份,则加上
                if (!provincePopupList.items.Contains(resultData[i]["province"].ToString()))
                    provincePopupList.AddItem(resultData[i]["province"].ToString());
            }
        }
        else  //请求出错
            print(www.error);
    }
    //请求天气情况的协程
    IEnumerator RequestWeatherData(string url)
    {
        lable.text = "";    //情况显示 
        WWW wwwWeather = new WWW(url);
        while (!wwwWeather.isDone)
        {
            yield return null;
        }
        if (wwwWeather.error == null)
        {
            #region 解析Json字符串,并显示,
            JsonData weatherData = JsonMapper.ToObject(wwwWeather.text);
            lable.text += "查询结果:\t" + weatherData["reason"].ToString() + "\n\n";
            JsonData skData = weatherData["result"]["sk"];
            lable.text += "当前实况天气:" + "\n";
            lable.text += "当前温度:\t" + skData["temp"].ToString() + "\n";
            lable.text += "当前风向:\t" + skData["wind_direction"].ToString() + "\n\n";
            lable.text += "当前风力:\t" + skData["wind_strength"].ToString() + "\n\n";
            lable.text += "当前湿度:\t" + skData["humidity"].ToString() + "\n\n";
            lable.text += "当前时间:\t" + skData["time"].ToString() + "\n\n";

            lable.text += "未来几天天气:" + "\n";
            JsonData futureData = weatherData["result"]["future"];

            for (int i = 0; i < futureData.Count; i++)
            {
                lable.text += "Week:" + "\t" + futureData[i]["week"].ToString() + "\n\n";
                lable.text += "Date:" + "\t" + futureData[i]["date"].ToString() + "\n";
                lable.text += "Temperature:" + futureData[i]["temperature"].ToString() + "\n\n";
                lable.text += "Weather:" + futureData[i]["weather"].ToString() + "\n\n";
                lable.text += "Wind:" + "\t" + futureData[i]["wind"].ToString() + "\n\n";
            }
            #endregion
        }
    }
}
Weather

编写完成脚本,保存,我们回到Unity中,将Weather脚本挂载到UIRoot上(随意),然后为其拖应用,然后,我们选择ProvincePopupList,在其UI PopupList组件上为其添加事件,将UI Root拖给Notify,选择方法SelectCity。类似,City Popup List添加事件SelectDistrict,DistrictPopup List添加事件 ShowWeather。好了,我们可以点击播放按钮,来测试下,如果没有意外的话,会出现如下界面:

技术分享
Ok,至此,我们的一个简单的关联下拉菜单就完成了。
ListJson : http://pan.baidu.com/s/1sjkS6vz%20 密码:mojf 
总结: 这个只是一个比较简单的实现关联下拉菜单的方法。也正是因为简单,它有许多问题,首先,我们不能使用UI上的值在代码中进行逻辑判断,其次,代码的耦合性较高,没有实现数据和显示的分离。后续,我会整理出一个比较完整的使用MVC模式的关联下拉菜单和查询天气的小Demo出来,期待吧,哈哈。

使用NGUI制作关联下拉菜单(查询全国天气)

标签:

原文地址:http://www.cnblogs.com/AhrenLi/p/4883992.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!