查询12306网站的车次信息

马上就要过年了,意味着一年一度的春运又来了,你准备好了?还在为不能买到合适的票发愁?作为一个有情怀的程序员,怎么能被这点小事困住?So,我们来做个小Demo来查询下12306的车次信息。是不是很期待。好了,废话不多说了,开工!

Talk is  cheap,show me code ! --Linus Benedict Torvalds

先明确几点,首先我们将用到聚合数据的资源,没有聚合数据账户的童鞋请去聚合数据官网注册,然后实名认证。然后,我们需要使用NGUI来搭建UI界面,关于NGUI插件,请看下我之前的文章。最后,我们需要解析Json数据,需要LisJson,没有的,也请看的我之前的文章。准备完毕后,我们开始。

我们创建一个文件夹,命名为“_Scripts”,用来存放我们的脚本文件。我们先写几个工具脚本,首先创建一个C#脚本,命名为Global,它用来保存我们请求数据需要用到的Url,appkey 和车次等信息。代码如下:

using UnityEngine;
using System.Collections;

public class Global {
    public static string appkey;    //你从聚合数据申请的appkey
    public static string urlTrain = "http://apis.juhe.cn/train/s";  //请求车次的url
    public static string trainName ;//= "g4";  //车次名称
}

Global

然后,我们保存,回到Unity中,创建第二个脚本,命名为NetWorkKit,它用来作为我们请求数据的工具类,在这个脚本中,我们使用协程来从聚合数据上请求数据,然后通过委托得到返回信息。关于请求数据,我这边主要写了两种方式,Get,Post 。对于委托还有http ,请求不了解的童鞋,请先去熟悉下。代码如下:

using UnityEngine;
using System.Collections;

public delegate void DidReceiveDataDelgate(string text);         //请求成功
public delegate void DidFailedDataDelgate(string error);         //请求失败
public class NetWorkKit : MonoBehaviour
{
    #region 单例
    private static NetWorkKit _instance = null;
    private NetWorkKit() { }
    public static NetWorkKit GetInstance()
    {
        if (_instance == null)
        {
            GameObject netObj = new GameObject("NetWorkKit");    //创建一个对象
            _instance = netObj.AddComponent<NetWorkKit>();       //为其添加NetWorkKit脚本, _instance 指向创建的实例
        }
        return _instance;     //返回该实例
    }
    #endregion
   //进行Get请求
    public void GetRequestData(string urlStr, DidReceiveDataDelgate didReceiveDataDelgate, DidFailedDataDelgate didFailedDataDelgate)
    {
        StartCoroutine(RequestData(urlStr, null, didReceiveDataDelgate, didFailedDataDelgate));   //开启协程
    }
    //进行Post请求,在这个Demo中没有用到,但是为了后续的扩展性,我们还是加上了
    public void PostRequestData(string urlStr, WWWForm form, DidReceiveDataDelgate didReceiveDataDelgate, DidFailedDataDelgate didFailedDataDelgate)
    {
        StartCoroutine(RequestData(urlStr, form, didReceiveDataDelgate, didFailedDataDelgate));    //开启协程
    }
    //协程,根据传进来的URL,从网站上请求数据,成功后,通过委托得到请求到的数据,失败类似
    IEnumerator RequestData(string urlStr, WWWForm form, DidReceiveDataDelgate didReceiveDataDelgate, DidFailedDataDelgate didFailedDataDelgate)
    {
        WWW www = null;
        if (form == null)
            www = new WWW(urlStr);    //进行Get请求
        else
            www = new WWW(urlStr, form);   //进行Post请求
        while (!www.isDone)
        {
            yield return null;   //等待请求完成
        }
        if (www.error == null)
            didReceiveDataDelgate(www.text);    //没有错误,外界通过向委托中传递方法来获得请求到的数据
        else
            didFailedDataDelgate(www.error);   //请求出错了,外界通过向委托中传递方法来获得错误信息
    }
}

NetWorkKit

保存,我们回到Unity中,现在,我们需要创建数据模型了。创建模型之前,我们先到聚合数据网站上看看,12306车次信息给我返回的数据是什么样的结构。我们根据这个结构来定义我们是数据模型。打开聚合数据,找到12306。 我们要用到其默认的 Json类型的返回数据。不了解Json 的童鞋,请先去了解下,很简单的。 我们看到,这个数据,有一个比较主要的字典,“train_info”,用来存放车次信息的,然后一个数组“station_list”用来保存了多个字典,存放了这个车次经过的站点信息。看完数据结构后,我们回到Unity中,创建文明的数据模型。首先,我们创建车次模型。创建一个C#脚本,命名为TrainModel,在这个脚本中,我们根据刚才看到的数据来定义我们的数据模型 ,这个脚本不需要继承MonoBehavoir。代码如下:

using UnityEngine;
using System.Collections;

public class TrainModel     //不需要继承MonoBehaviour
{
    /* "name": "G656",
       "start": "西安北",
       "end": "北京西",
       "starttime": "10:10",
       "endtime": "16:27",
       "mileage": "1212km"
    */
    public string trainName;       //车名
    public string trainStart;      //始发站
    public string trainEnd;        //终点站
    public string trainStartTime;  //出发时间
    public string trainEndTime;    //到站时间
    public string trainMileage;    //距离

    //私有化默认构造函数
    private TrainModel() { }
    //构造函数
    private TrainModel(string trainName, string trainStart, string trainEnd, string trainStartTime, string trainEndTime, string trainMileage)
    {
        Init(trainName, trainStart, trainEnd, trainStartTime, trainEndTime, trainMileage);
    }
    //初始化函数
    private void Init(string trainName, string trainStart, string trainEnd, string trainStartTime, string trainEndTime, string trainMileage)
    {
        this.trainName = trainName;
        this.trainStart = trainStart;
        this.trainEnd = trainEnd;
        this.trainStartTime = trainStartTime;
        this.trainEndTime = trainEndTime;
        this.trainMileage = trainMileage;
    }
    //静态的创建TrainModel的方法
    public static TrainModel Create(string trainName, string trainStart, string trainEnd, string trainStartTime, string trainEndTime, string trainMileage)
    {
        return new TrainModel(trainName, trainStart, trainEnd, trainStartTime, trainEndTime, trainMileage);
    }
    //静态的创建TrainModel的方法  ,这个方法在后面的显示脚本中会用到
    public static TrainModel CreateModel(TrainModel model)
    {
        return new TrainModel(model.trainName, model.trainStart, model.trainEnd, model.trainStartTime, model.trainEndTime, model.trainMileage);
    }
}

TrainModel

保存,回到Unity中,我们创建站点的数据模型。创建C#脚本,命名为StationModel,跟TrainModel类似。代码如下:

using UnityEngine;
using System.Collections;

public class StationModel            //不需要继承MonoBehaviour
{
    /*
      train_id int 站点序号
    station_name string 站点名称
    arrived_time string 到达时间
    leave_time string 发车时间
    stay string 停留
    mileage string 里程
    ssoftSeat string 二等座
    fsoftSeat string 一等座
    hardSead string 硬座
    softSeat string 软座
    hardSleep string 硬卧
    softSleep string 软卧
    wuzuo string 无座
    swz string 商务座
    tdz string 特等座
    gjrw string 高级软卧
     */
    public string stationID;        //站点序号
    public string stationName;      //站点名称
    public string stationArrivedTime;   //到达时间
    public string stationLeaveTime;     //发车时间
    public string stationMileage;      //里程
    public string stationFsoftSeat;     //一等座
    public string stationSsoftSeat;    //二等座
    public string stationHardSeat;      //硬座
    public string stationSoftSeat;      //软座
    public string stationHardSleep;     //硬卧
    public string stationSoftSleep;     //软卧
    public string stationWuZuo;         //无座
    public string stationSWZ;           //商务座
    public string stationTDZ;           //特等座
    public string stationGJRW;          //高级软卧
    public string stationStay;          //停留

    //私有化默认构造函数
    private StationModel() { }
    //构造函数
    private StationModel(string stationID, string stationName, string stationArrivedTime,
         string stationLeaveTime, string stationMileage, string stationFsoftSeat,
         string stationSsoftSeat, string stationHardSeat, string stationSoftSeat,
         string stationHardSleep, string stationSoftSleep, string stationWuZuo,
         string stationSWZ, string stationTDZ, string stationGJRW, string stationStay)
    {
        Init(stationID, stationName, stationArrivedTime,
          stationLeaveTime, stationMileage, stationFsoftSeat,
          stationSsoftSeat, stationHardSeat, stationSoftSeat,
          stationHardSleep, stationSoftSleep, stationWuZuo,
          stationSWZ, stationTDZ, stationGJRW, stationStay);
    }
    //初始化函数
    private void Init(string stationID, string stationName, string stationArrivedTime,
         string stationLeaveTime, string stationMileage, string stationFsoftSeat,
         string stationSsoftSeat, string stationHardSeat, string stationSoftSeat,
         string stationHardSleep, string stationSoftSleep, string stationWuZuo,
         string stationSWZ, string stationTDZ, string stationGJRW, string stationStay)
    {
        this.stationID = stationID;
        this.stationName = stationName;
        this.stationArrivedTime = stationArrivedTime;
        this.stationLeaveTime = stationLeaveTime;
        this.stationMileage = stationMileage;
        this.stationFsoftSeat = stationFsoftSeat;
        this.stationSsoftSeat = stationSsoftSeat;
        this.stationHardSeat = stationHardSeat;
        this.stationSoftSeat = stationSoftSeat;
        this.stationHardSleep = stationHardSleep;
        this.stationSoftSleep = stationSoftSleep;
        this.stationWuZuo = stationWuZuo;
        this.stationSWZ = stationSWZ;
        this.stationTDZ = stationTDZ;
        this.stationGJRW = stationGJRW;
        this.stationStay = stationStay;
    }
    //静态的创建StationModel的方法
    public static StationModel Create(string stationID, string stationName, string stationArrivedTime,
         string stationLeaveTime, string stationMileage, string stationFsoftSeat,
         string stationSsoftSeat, string stationHardSeat, string stationSoftSeat,
         string stationHardSleep, string stationSoftSleep, string stationWuZuo,
         string stationSWZ, string stationTDZ, string stationGJRW, string stationStay)
    {
        return new StationModel(stationID, stationName, stationArrivedTime,
          stationLeaveTime, stationMileage, stationFsoftSeat,
          stationSsoftSeat, stationHardSeat, stationSoftSeat,
          stationHardSleep, stationSoftSleep, stationWuZuo,
          stationSWZ, stationTDZ, stationGJRW, stationStay);
    }
    //静态的创建StationModel的方法  ,这个方法在后面的显示脚本中会用到
    public static StationModel CreateModel(StationModel model)
    {
        return new StationModel(model.stationID, model.stationName, model.stationArrivedTime,
             model.stationLeaveTime, model.stationMileage, model.stationFsoftSeat,
             model.stationSsoftSeat, model.stationHardSeat, model.stationSoftSeat,
             model.stationHardSleep, model.stationSoftSleep, model.stationWuZuo,
             model.stationSWZ, model.stationTDZ, model.stationGJRW, model.stationStay);
    }
}

StationModel

好了,我们模型类定义好了,下面来创建控制显示的类,这个类负责从网站上请求数据,并解析出来。我们创建一个脚本,命名为TrainController 。在这个脚本中,我们使用单例。因为,我们这个脚本不需要继承MonoBehaviour。我们要保证,在运行过程中,只有一个实例去负责请求数据。代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;     //泛型
using LitJson;      //导入LitJson

public delegate void DidLoadedTrainDataDelgate(Dictionary<string, TrainModel> trainDic);    //请求到车次数据的委托
public delegate void DidLoadedStationDataDelgate(Dictionary<string, Dictionary<string, StationModel>> stationDic); //请求到站点数据的委托
public delegate void DidFailedDelgate(string error);   //没有对应车次的委托
public class TrainController    //不需要继承MonoBehaviour
{
    #region 单例
    private static TrainController _instance = null;
    private TrainController()
    {
        nwk = NetWorkKit.GetInstance();   //获取NetWorkKit实例
    }
    public static TrainController GetInstance()    //静态的获取实例方法
    {
        if (_instance == null)
            _instance = new TrainController();
        return _instance;
    }
    #endregion
    private static NetWorkKit nwk;      //定义NetWorkKit的实例
    /// <summary>
    /// 进行Get请求,我们使用lambda表达式来获取数据,并解析
    /// </summary>
    /// <param name="didLoadedTrainDataDelgate">请求到车次信息</param>
    /// <param name="didLoadedStationDataDelgate">请求到站点信息</param>
    /// <param name="didFailedDelgate">请求不到用户输入的车次,给用户一个提示</param>
    public void GetTrainStationInfo(DidLoadedTrainDataDelgate didLoadedTrainDataDelgate, DidLoadedStationDataDelgate didLoadedStationDataDelgate, DidFailedDelgate didFailedDelgate)
    {
        Dictionary<string, TrainModel> trainDic = new Dictionary<string, TrainModel>();  //用来存放车次信息的字典
        //用来存放站点信息的字典,关于这两个字典的定义,可以根据返回的数据类型来定义,格式不唯一
        Dictionary<string, Dictionary<string, StationModel>> stationDic = new Dictionary<string, Dictionary<string, StationModel>>();
        string urlStr = Global.urlTrain + "?name=" + Global.trainName + "&key=" + Global.appkey; //拼接请求需要的Url
        nwk.GetRequestData(urlStr, (string dateText) =>
        {
            //使用Try - catch 语句,防止查询不到对应的车次,程序报错
            try
            {
                #region 解析数据 ,并将解析出来的数据加到我们创建的对应的字典中
                JsonData root = JsonMapper.ToObject(dateText);  //将json字符串转换为 JsonData 对象
                JsonData result = root["result"];             //继续往下
                JsonData trainInfo = result["train_info"];    //获取车次信息的JsonData 对象
                JsonData stationList = result["station_list"];  //获取站点信息 数组的JsonData 对象
                //创建车次模型
                TrainModel train = TrainModel.Create(trainInfo["name"].ToString(), trainInfo["start"].ToString(), trainInfo["end"].ToString(), trainInfo["starttime"].ToString(), trainInfo["endtime"].ToString(), trainInfo["mileage"].ToString());
                //将车次名称作为Key,车次模型实例作为Value加到我们的车次字典中
                trainDic.Add(Global.trainName, train);
                //定义站点数据字典,Key为站点序号,Value为站点模型
                Dictionary<string, StationModel> dic = new Dictionary<string, StationModel>();
                //遍历整个站点数组
                for (int i = 0; i < stationList.Count; i++)
                {
                    JsonData data = stationList[i];   //获取站点的JsonData 对象
                    //创建站点模型
                    StationModel station = StationModel.Create(data["train_id"].ToString(), data["station_name"].ToString(), data["arrived_time"].ToString(), data["leave_time"].ToString(),
                        data["mileage"].ToString(), data["fsoftSeat"].ToString(), data["ssoftSeat"].ToString(), data["hardSead"].ToString(), data["softSeat"].ToString(),
                        data["hardSleep"].ToString(), data["softSleep"].ToString(), data["wuzuo"].ToString(), data["swz"].ToString(), data["tdz"].ToString(),
                        data["gjrw"].ToString(), data["stay"].ToString());
                    dic.Add(data["train_id"].ToString(), station);  //将站点模型加入到站点数据字典
                }
                //将得到的包含所有站点的站点字典加入站点信息字典
                stationDic.Add("station_list", dic);
                #endregion

                if (didLoadedTrainDataDelgate != null)
                    didLoadedTrainDataDelgate(trainDic);    //如果外界传进来这个方法了,则将车次字典传过去
                if (didLoadedStationDataDelgate != null)
                    didLoadedStationDataDelgate(stationDic);  //如果外界传进来这个方法了,则将站点信息字典传过去
            }
            catch (System.Exception)       //查询不到用户输入从车次
            {
                if (didFailedDelgate != null)
                    didFailedDelgate("对不起,没有找到对应的车次");
                Debug.Log("输入信息有误");
            }
        }, null);     //我们暂不考虑请求失败的情况
    }
}

TrainController

好了,我们的控制脚本也编写完毕了,保存,回到Unity中,我们开始控制显示了。为了能更好的显示,我们需要先大概的搭建一个UI界面。这个我不在行,搭出来的UI比较丑,请见谅。。。

首先,我们需要明确我们需要那些部件。这里,我将其分为3大块,第一个的我们的核心,用来获取用户输入的车次,点击查询按钮后,有两个label 负责显示车次信息,和站点信息。在车次信息的label里,我们不能保证我们的label一定能够完成显示车次信息,为了保险起见,我们为label添加BoxCollider 组件后添加UITextList组件,这样label就可以拖动了。当然,你也可以为添加Scroll Bar,用来拖动。在负责显示站点信息的Label也需要同样的操作。另外,我们还需要提供两个Button,来控制切换站点。第二部分,是我们的输入appkey页面,在这个页面,我们需要用户输入他从聚合数据申请的appkey ,然后我们使用这个appkey去请求数据。第三部分,用来提示用户,没有找到对应的车次信息。好了,具体的UI界面大家可以去搭建。另外,我们是程序,没有必要话费过多d时间去摆UI,设计界面。我这里展示下,我是Hierarchy面板,方便大家参考

搭建完UI后,我们来编写脚本,控制我们的数据显示。创建脚本,命名为UIView。在这个脚本中,会有许多引用。我会尽量写清注释,方便你看懂。当然,你可以按照自己喜欢的方式来。毕竟每个人的习惯不一样。代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UIView : MonoBehaviour
{
    public UILabel inputLabel;      //用来接收用户输入的车次名称
    public GameObject trainInfoShow;        //车次信息展示 在其下挂有label用来显示车次信息
    public GameObject stationInfoShow;      //站点信息展示 在其下挂有label用来显示站点信息
    public UIButton backButton;     //上一站   点击后切换到上一个站点
    public UIButton nextButton;     //下一站   点击后切换到下一个站点

    public GameObject errorShow;      //错误信息  在其下挂有label用来显示错误信息
    public GameObject query;        //查询管理对象
    public GameObject appkey;       //Appkey 管理对象

    private TrainController trainController;    //TrainController的引用
    private TrainModel trainModel;      // 车次模型
    private List<StationModel> stationModelsList;    //用来存放我们获取到的站点
    private int selectedIndex = 0;   //当前选中的站点在stationModelList中的索引
    private int length = 0;     //stationModelList 的长度,用来表示有多少个站点

    private UITextList trainLabel;    //展示车次信息,将其做成可拖拽,方便查看
    private UITextList stationLabel;   //展示站点信息,将其做成可拖拽,方便查看
    private UILabel errorLabel;     //展示出错信息
    private UILabel appkeyLabel;    //用来接收用户输入的appkey
    void Start()
    {
        //获得引用,赋值等操作,并将一开始不显示的组件隐藏
        trainController = TrainController.GetInstance();
        query.SetActive(false);
        trainInfoShow.SetActive(false);
        stationInfoShow.SetActive(false);
        backButton.gameObject.SetActive(false);
        nextButton.gameObject.SetActive(false);
        errorShow.SetActive(false);
        trainLabel = trainInfoShow.transform.FindChild("TrainLabel").GetComponent<UITextList>();
        stationLabel = stationInfoShow.transform.FindChild("StationLabel").GetComponent<UITextList>();
        errorLabel = errorShow.transform.FindChild("ErrorLabel").GetComponent<UILabel>();
        appkeyLabel = appkey.transform.FindChild("AppKeyInput Field/Label").GetComponent<UILabel>();
        stationModelsList = new List<StationModel>();
    }
    //点击了查询按钮,它将添加到查询按钮和InputField的提交 事件
    public void OnQuaryButtonClick()
    {
        if (inputLabel.text != "" && Global.appkey != "")
        {
            //如果用户输入了appkey,和车次名称,则需要我们去请求数据
            #region  坑 坑 坑 // textList在激活后会清空label的显示,所以我们需要在请求数据之前,就激活它,并且最好手动清空一次
            trainInfoShow.SetActive(true);
            trainLabel.Clear();
            stationInfoShow.SetActive(true);
            stationLabel.Clear();
            #endregion

            #region 查询数据
            Global.trainName = inputLabel.text;    //获取用户输入的车次名称
            //调用 GetTrainStationInfo请求数据 并用请求到的数据来刷新显示
            trainController.GetTrainStationInfo((Dictionary<string, TrainModel> trainDic) =>
            {
                //这里也需要注意,我们为什么不直接使用我们获取到的模型?
                //原因是,我们如果使用获取到的模型,如果后续我们操作模型的话,
                //由于模型是引用类型的,我们修改的话,会导致模型变化,
                //下次再使用的话,模型就变了,导致程序出现莫名其妙的Bug。
                //所以我们在模型类中添加一个静态的通过模型来构建新模型的方法,
                //修改的话修改的是后来重新创建的模型,跟我们直接获取的模型没有关系
                trainModel = TrainModel.CreateModel(trainDic[Global.trainName]);
                UpdateTrainInfo();   //更新车次显示
            },
            (Dictionary<string, Dictionary<string, StationModel>> stationDic) =>
            {
                stationModelsList.Clear();  //清空站点列表
                //定义一个站点数据字典,用来保存获取到的站点信息
                Dictionary<string, StationModel> dic = stationDic["station_list"];
                //遍历所有的站点
                foreach (string id in dic.Keys)
                {
                    //将站点加到stationModelsList中
                    stationModelsList.Add(StationModel.CreateModel(dic[id]));
                }
                selectedIndex = 0;    //初始选中的站点索引更新为第一个
                length = stationModelsList.Count;  //获得站点的个数,
                UpdateStationInfo();    //更新站点显示
            },
            (string error) =>
            {
                HideShow();     //隐藏显示
                UpdateErrorInfo(error);   //更新出错显示
            });
            #endregion
        }
    }
    //更新车次显示
    private void UpdateTrainInfo()
    {
        errorShow.SetActive(false);      //隐藏错误信息展示
        trainInfoShow.SetActive(true);   //激活车次信息展示
        trainLabel.Clear();    //每次更新,都要清空一遍
        //将车次信息加到textList中
        trainLabel.Add("车次:" + "\t" + trainModel.trainName);
        trainLabel.Add("始发站:" + "\t" + trainModel.trainStart);
        trainLabel.Add("终点站:" + "\t" + trainModel.trainEnd);
        trainLabel.Add("出发时间:" + "\t" + trainModel.trainStartTime);
        trainLabel.Add("到站时间:" + "\t" + trainModel.trainEndTime);
        trainLabel.Add("距离:" + "\t" + trainModel.trainMileage);
    }
    //更新站点显示
    private void UpdateStationInfo()
    {
        stationInfoShow.SetActive(true);   //激活站点显示
        backButton.gameObject.SetActive(true);  //激活“上一站”按钮
        nextButton.gameObject.SetActive(true);  //激活“下一站”按钮
        stationLabel.Clear();    //每次更新,都要清空一遍
        //将当前选中的站点信息加到站点textList中
        stationLabel.Add("序号:" + "\t" + stationModelsList[selectedIndex].stationID.ToString());
        stationLabel.Add("名称:" + "\t" + stationModelsList[selectedIndex].stationName.ToString());
        stationLabel.Add("到达时间:" + "\t" + stationModelsList[selectedIndex].stationArrivedTime.ToString());
        stationLabel.Add("停留:" + "\t" + stationModelsList[selectedIndex].stationStay.ToString());
        stationLabel.Add("发车时间:" + "\t" + stationModelsList[selectedIndex].stationLeaveTime.ToString());
        stationLabel.Add("里程:" + "\t" + stationModelsList[selectedIndex].stationMileage.ToString());
        stationLabel.Add("一等座:" + "\t" + stationModelsList[selectedIndex].stationFsoftSeat.ToString());
        stationLabel.Add("二等座:" + "\t" + stationModelsList[selectedIndex].stationSsoftSeat.ToString());
        stationLabel.Add("硬座:" + "\t" + stationModelsList[selectedIndex].stationHardSeat.ToString());
        stationLabel.Add("软座:" + "\t" + stationModelsList[selectedIndex].stationSoftSeat.ToString());
        stationLabel.Add("硬卧:" + "\t" + stationModelsList[selectedIndex].stationHardSleep.ToString());
        stationLabel.Add("软卧:" + "\t" + stationModelsList[selectedIndex].stationSoftSleep.ToString());
        stationLabel.Add("无座:" + "\t" + stationModelsList[selectedIndex].stationWuZuo.ToString());
        stationLabel.Add("商务座:" + "\t" + stationModelsList[selectedIndex].stationSWZ.ToString());
        stationLabel.Add("特等座:" + "\t" + stationModelsList[selectedIndex].stationTDZ.ToString());
        stationLabel.Add("高级软卧:" + "\t" + stationModelsList[selectedIndex].stationGJRW.ToString());
    }
    //更新错误信息
    private void UpdateErrorInfo(string error)
    {
        errorShow.SetActive(true);    //激活错误信息展示
        errorLabel.text = error;      //显示错误信息
    }
    //隐藏显示
    private void HideShow()
    {
        trainInfoShow.SetActive(false);
        stationInfoShow.SetActive(false);
        backButton.gameObject.SetActive(false);
        nextButton.gameObject.SetActive(false);
    }
    //点击了上一站按钮后执行
    public void OnBackButtonClick()
    {
        selectedIndex--;      //当前选中的站点索引减一
        if (selectedIndex == -1)       //如果索引越界,让其等于最后一个站点索引
            selectedIndex = length - 1;
        UpdateStationInfo();     //更新站点显示
    }
    //点击了下一站按钮后执行
    public void OnNextButtonClick()
    {
        selectedIndex++;     //当前选中的站点所有增一
        selectedIndex %= length;     //对长度取余,防止索引越界
        UpdateStationInfo();     //更新站点显示
    }
    //点击了OK按钮后执行,我们需要先输入appkey然后点击OK按钮,才可以输入车次名称,然后查询
    public void OnOKButtonClick()
    {
        if (appkeyLabel.text == "")
        {
            UpdateErrorInfo("Appkey不可用,请重新输入!");
        }
        else
        {
            Global.appkey = appkeyLabel.text;
            appkey.SetActive(false);
            query.SetActive(true);
        }
    }
}

UIView

好了,保存脚本,回到Unity中,我们为其拖引用。我这边看下我的拖完引用后的样子

完事后,我们点击播放,我们会看到如下界面

我们拷贝我们从聚合数据申请到的appkey,输入,点击确定,然后再输入框输入车次名称,我这里输入G235,点击查询,稍等片刻,就可以看到我们已经请求到了G235的车次和站点信息。如下:

好了,到此一个简单的查询12306车次信息的Demo就玩成了。

总结:在这个Demo中,我们使用了经典的MVC框架结构。这一点在脚本命名上就能很直观的体现出来。关于MVC框架,我不是很精通,但是会用。我之前有个老师告诉我,所谓设计模式,程序框架都是纸老虎。真正想靠一种或两种设计模式来完成一个项目还是很困难的。有些东西,不宜过度设计,简约就是最好的形态。代码也是如此。扯远了。。。回到我们这个Demo中来,我觉得这个Demo还是用很多可以值得研究和改进的地方,比如,单例,json,www,委托等,另外我们的功能还太单一,只能查询车次和对应的站点信息,我们还可以试着增加其他的功能。

Unity常用资源下载:http://www.cnblogs.com/AhrenLi/p/4887095.html

时间: 2024-10-03 14:02:03

查询12306网站的车次信息的相关文章

12306网站信息泄漏查询页面

还有1天就2015年了,离着中国人的新年也快了,买票的人越来越多了,有的人买到了,有的人没买到.对于这种提前售票的新规定,最大的受益者是其实是黄牛党.先买再退票,坑爹! 最近12306网站很火,除了春运买票,就是12306信息泄漏的新闻,我们的大wooyun平台(我也是平台的一名白帽子)在圣诞节那天爆出大量用户信息泄漏,居然都上了CCAV,一时间轩然大波,事后和朋友们仔细分析了一下,其实就是从以前被拖的17173等裤子里撞出来的,泄漏的数据也就只有13w条,不存在所谓的22G的数据.无论如何还是

阿里云确认向12306提供了技术协助,负责承接12306网站75%的余票查询流量

公开数据显示,今年春运火车票售卖的最高峰日出现在2014年12月19日.12306网站访问量(PV值)达到破纪录的297亿次,平均每秒PV超过30万次.当天共发售火车票956.4万张,其中互联网发售563.9万张,占比59%,均创历年春运新高.阿里云计算日前予以确认,确实向12306提供了技术协助,负责承接12306网站75%的余票查询流量.至于合作的具体细节,阿里云方面称将适时对外公布. 12306网站曾被认为是“全球最忙碌的网站”,在应对高并发访问处理方面备受网民诟病.经此一役,阿里云计算将

python 3.6 tkinter+urllib+json 火车车次信息查询

--------blogs:  陈月白    http://www.cnblogs.com/chenyuebai    -------- 一.概述 妹子工作时需要大量地查询火车车次至南京的信息,包括该车次到达站(南京站or南京南站).到达时间.出发时间等,然后根据这些信息做下一步工作. 版本结束,趁着间歇期,帮她弄了个简易的批量查询工具,粉色的按钮是给她用的~哈哈哈! (?*?*?) 大概80行代码,主要是: 界面读取待查询车次 - - - - 调用车次信息接口- - - - 解析返回数据 -

假如我来架构12306网站---文章来自csdn(Jackxin Xu IT技术专栏)

(一)概论 序言:  此文的撰写始于国庆期间,当中由于工作过于繁忙而不断终止撰写,最近在设计另一个电商平台时再次萌发了完善此文并且发布此文的想法,期望自己的绵薄之力能够给予各位同行一些火花,共同推进国内的大型在线交易系统的研发工作,本文更多地站在软件工程角度来看待整个问题,有关后续的技术问题研究,将在另外的博文中予以探讨. 一年一度的国庆大假刚落下帷幕,由于这次长假是历史上最长的一次,因此出行问题备受关注,而铁路出行作为最主要的出行方式更是大家讨论的热点,老生常谈的购票难问题又被提起.这几天我在

java抓取12306火车余票信息

最近在弄一个微信的公众帐号,涉及到火车票查询,之前用的网上找到的一个接口,但只能查到火车时刻表,12306又没有提供专门的查票的接口.今天突然想起自己直接去12306上查询,抓取查询返回的数据包,这样就可以得到火车票的信息.这里就随笔记一下获取12306余票的过程. 首先,我用firefox浏览器上12306查询余票.打开firefox的Web控制台,选上网络中的"记录请求和响应主体" 然后输入地址日期信息之后点击网页上的查询按钮,就能在Web控制台下看到网页请求的地址了: 就是图片中

关于数字证书理解的简单整理以及12306网站证书简单分析

首先简单理解一下什么是数字证书.这里是一篇英文文档,描述的很形象.形象的描述了什么是公钥,什么是私钥,如果确保数字证书的可靠性等. 下面,我们看一个应用"数字证书"的实例:https协议.这个协议主要用于网页加密. 一般我们电脑的浏览器中都有一些受信任的证书颁发机构列表, 里边存储的都是一些机构的信息.这些机构都是权威的.当然可以通过安装软件的方式,来增加证书颁发机构,比如中国银行的根证书软件,阿里巴巴的根证书软件.默认我们认为这些软件都是从官网下载的,是绝对的没被篡改的,可靠的.简单

查询类网站或成站长淘宝客新金矿

流量是玩转互联网的基础,传说的中的大牛一般都是倒腾流量的高手.在大牛眼中抓取流量是一门艺术,背后玩的是五花八门的思路. 这篇文章斗胆跟大家分享一个好玩的思路.文章将以剥洋葱的方式展开,希望剥完这颗洋葱会让你有相见恨晚之感. 在切入正题之前,先分析一下搜索需求这个概念.人们借助搜索引擎大抵有以下几个诉求:第一,了解是什么,寻找是什么类别的信息,这一块占据搜索流量的绝大部分.第二,想知道为什么,很多时候会用提问关键词去索引,譬如"怎么获取流量".第三类,单纯地想去某个网站,敲入关键词通过搜

12306网站正替谁挨骂?

又到一年春运时,因铁道部规定车票可以提前60天购买,如今这个时间段,12306网站基本已经度过最难熬的时期,但关于这个简陋网站的讨论,更确切地说是吐槽和谩骂远没有停止:抢不到票的人自然有理由抱怨12306系统缓慢,用户体验垃圾得要死:抢到票的人也会心有余悸地发泄一番,毕竟,抢票的过程总是伴随着心跳加速和手指抽筋,不吐槽也很容易过不好年. 12306网站成立以来,不断改善也不断遭遇吐槽,按照正常逻辑上讲,它算得上铁道部的一大进步.事实上,没有网络购票的时候,笔者一般是不去火车站的,一方面可能真不需

从各大高校到12306网站看SSL问题

最近闲来无事,看了许多高校的数字信息平台以及12306官网,从中发现了一个问题--高校"联合"12306正在培养学生"坏习惯".作为一名学生,我想有两个网站不得不去登录,一个是学校的数字信息平台,不登录无法查询自己的成绩等等:另一个是12306,学生往返火车票需要订购--特别是现在激烈的抢票大战,哪么,作为高校学生必须要登录的两个网站,安全性怎么样呢? 作为服务于广大群体的两个网站来说,都有其安全意识.但我要说的是,正是这种不完善的安全意识培养了广大学生群体的不良习