Xamarin.Forms开发天气预报app

Xamarin.Forms开发天气预报app

大家好,这是我第一次发技术博客,今天给大家介绍在Xamarin.Forms底下如何开发原生跨平台天气预报app,希望能帮到大家,也欢迎大家能跟我探讨问题。
首先要配置VS For Xamarin,这网上有教程,这里就不介绍了。
废话不说,先给大家展示我的产品:

博主有点懒,图片懒得调了, 下面介绍怎么实现:
1.创建可移植项目。
2.调用新浪天气接口,简单方便,利用url直接申请,返回xml字符串( http://php.weather.sina.com.cn/xml.php?city=%C4%CF%B2%FD&password=DJOYnieT8234jlsK&day=0,其中city后面跟的是城市的url编码,password固定,day表示你要查询哪一天,0表示今天,1表示明天,2表示后天)。
3.解析xml字符串,得到天气数据。
下面讲解具体要怎么做:
1.创建xaml页面,布局如下:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DemoWeather.Page1" BackgroundImage="timg2.jpg">
  <RelativeLayout>
    <StackLayout Orientation="Vertical">
        <StackLayout Orientation="Horizontal" HeightRequest="50"  Padding="20,0">
            <Label Text="输入城市:" HorizontalOptions="Start" VerticalOptions="Center"></Label>
            <Entry x:Name="CityName" HorizontalOptions="FillAndExpand" VerticalOptions="Center"></Entry>
        </StackLayout>
      <StackLayout  Padding="20,0">
          <Button Text="确定" x:Name="Sure_Btn" Clicked="Sure_Btn_OnClicked" BackgroundColor="#00888C" BorderRadius="5" BorderWidth="1"></Button>
      </StackLayout>
      <Label x:Name="lab" IsVisible="False" HorizontalOptions="FillAndExpand" BackgroundColor="Gray" Opacity="0.4" HeightRequest="10"></Label>
        <ListView x:Name="ListCity" RowHeight="150" HorizontalOptions="Fill" VerticalOptions="FillAndExpand">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid Padding="20,0" HeightRequest="150" VerticalOptions="FillAndExpand">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"></RowDefinition>
                                <RowDefinition Height="*"></RowDefinition>
                            </Grid.RowDefinitions>
                            <Image Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Source="{Binding WeatherImage}"></Image>
                            <Label Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Text="{Binding Days}" FontSize="30" VerticalTextAlignment="Center" HorizontalOptions="Center"></Label>
                            <Label Grid.Row="0" Grid.Column="2" Text="{Binding TemperatureL}" FontSize="26" VerticalTextAlignment="Center" HorizontalOptions="Center"></Label>
                            <Label Grid.Row="1" Grid.Column="2" Text="{Binding Weather}" FontSize="26" VerticalTextAlignment="Center" HorizontalOptions="Center"></Label>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
    <Frame RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.3,Constant=0}"
           RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.1,Constant=0}"
           RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.8,Constant=0}"
           RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.5,Constant=0}" 
           BackgroundColor="Transparent" IsVisible="False" x:Name="SuggestFrame">
      <RelativeLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" x:Name="Rlayout">
        <Image Source="paper.png" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"></Image>
        <Label RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,ElementName=Rlayout,Property=Y,Factor=0.7,Constant=0}"
               RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView,ElementName=Rlayout,Property=X,Factor=0.3,Constant=0}"
               RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.8,Constant=0}"
               RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.5,Constant=0}"
               HorizontalTextAlignment="Center" VerticalTextAlignment="Center" FontSize="16" x:Name="SuggestLabel" TextColor="Black" LineBreakMode="WordWrap"></Label>
      </RelativeLayout>
    </Frame>
    <Button RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.9,Constant=0}"
            RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.1,Constant=0}"
            RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.8,Constant=0}"
            HeightRequest="50"  Text="出行建议" BackgroundColor="#0088CC" BorderRadius="5" BorderWidth="1" x:Name="Suggest_Btn"
            IsVisible="False" Clicked="Suggest_Btn_OnClicked"></Button>
      <Button RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0,Constant=0}"
              RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0,Constant=0}"
              RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=1,Constant=0}"
              RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=1,Constant=0}"
              BackgroundColor="Black" Opacity="0.4" IsVisible="False" x:Name="ExitBtn" Clicked="ExitBtn_OnClicked"></Button>
  </RelativeLayout>
</ContentPage>
2.后台代码:
 public partial class Page1 : ContentPage
    {
        private string SuggestStr;//出行建议字符串
        private string StrUrl = "";//请求数据url字符串
        public Page1()
        {
            InitializeComponent();
            ListCity.ItemSelected += (o, e) => { ListCity.SelectedItem = null; };
        }
        /// <summary>
        /// 按键查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Sure_Btn_OnClicked(object sender, EventArgs e)
        {
            List<WeatherInfo> weatherInfos;
           XmlReader xmlReaders;
           
            if (string.IsNullOrWhiteSpace(CityName.Text))
            {
                toast.GetToast("请输入城市地址!");
                return;
            }
             string SCity = CityName.Text;
            weatherInfos = new List<WeatherInfo>() { new WeatherInfo(), new WeatherInfo(), new WeatherInfo() };
            string UrlCity = GetUrlEncoder.UrlEncode(SCity, "GB2312");
            StrUrl = "http://php.weather.sina.com.cn/xml.php?city=" + UrlCity + "&password=DJOYnieT8234jlsK&day=";
            XmlReaderSettings settings;
            settings = new XmlReaderSettings();
            settings.IgnoreComments = true;
            List<string> strs = new List<string>();
            strs.Clear();
            string str3 = "", str4 = "";
            
            for (int i = 0; i < 3; i++)
            {
                string str = StrUrl + i;
                strs.Add(str);
                xmlReaders = XmlReader.Create(strs[i],settings);
                while (xmlReaders.Read())
                {
                    if (xmlReaders.NodeType == XmlNodeType.Element)
                    {
                        
                        if (xmlReaders.Name == "city")
                        {
                            if (i==0)
                            {
                                weatherInfos[i].Days = "今天";
                            }
                            if (i == 1)
                            {
                                weatherInfos[i].Days = "明天";
                            }
                            if (i==2)
                            {
                                weatherInfos[i].Days = "后天";
                            }
                            weatherInfos[i].CityName = xmlReaders.ReadElementContentAsString();
                        }
                        if (xmlReaders.Name == "status1")
                        {
                            str3 = xmlReaders.ReadElementContentAsString();
                        }
                        if (xmlReaders.Name == "status2")
                        {
                            string str1 = xmlReaders.ReadElementContentAsString();
                            if (!string.IsNullOrEmpty(str1)&& !string.IsNullOrWhiteSpace(str3)&&str3!=str1)
                            {
                                weatherInfos[i].Weather = str3 + "转" + str1;
                                weatherInfos[i].WeatherImage = ImageTemplate.DicImage[str3];
                            }
                            else if ((!string.IsNullOrEmpty(str1) && string.IsNullOrWhiteSpace(str3))||str3==str1)
                            {
                                weatherInfos[i].Weather = str1;
                                weatherInfos[i].WeatherImage = ImageTemplate.DicImage[str1];
                            }
                            else if (string.IsNullOrEmpty(str1) && !string.IsNullOrWhiteSpace(str3))
                            {
                                weatherInfos[i].Weather = str3;
                                weatherInfos[i].WeatherImage = ImageTemplate.DicImage[str3];
                            }
                        }
                        if (xmlReaders.Name == "temperature1")
                        {
                            str4 = xmlReaders.ReadElementContentAsString();
                        }
                        if (xmlReaders.Name == "temperature2")
                        {
                            string str2 = xmlReaders.ReadElementContentAsString();
                            if (!string.IsNullOrEmpty(str2)&&!string.IsNullOrWhiteSpace(str4)&&str4!=str2)
                            {
                                weatherInfos[i].TemperatureL = str4 + "-" + str2+"℃";
                            }
                            else if(!string.IsNullOrEmpty(str2) && string.IsNullOrWhiteSpace(str4))
                            {
                                weatherInfos[i].TemperatureL = str2 + "℃";
                            }
                            else if (string.IsNullOrEmpty(str2) && !string.IsNullOrWhiteSpace(str4))
                            {
                                weatherInfos[i].TemperatureL = str4 + "℃";
                            }
                        }
                        if (i==1)
                        {
                            if (xmlReaders.Name == "chy_shuoming")
                            {
                                SuggestStr = xmlReaders.ReadElementContentAsString() + "\n";
                            }
                            if (xmlReaders.Name=="ssd_s")
                            {
                                SuggestStr += xmlReaders.ReadElementContentAsString()+"\n";
                            }
                            if (xmlReaders.Name=="yd_s")
                            {
                                SuggestStr += xmlReaders.ReadElementContentAsString() + "\n";
                            }
                        }
                          
                    }
                }
            }
            lab.IsVisible = true;
            Suggest_Btn.IsVisible = true;
            ListCity.ItemsSource = weatherInfos;  
        }
        /// <summary>
        /// 出行建议
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Suggest_Btn_OnClicked(object sender, EventArgs e)
        {
            SuggestFrame.IsVisible = true;
            ExitBtn.IsVisible = true;
            SuggestLabel.Text = SuggestStr;
        }


        private void ExitBtn_OnClicked(object sender, EventArgs e)
        {
            SuggestFrame.IsVisible = false;
            ExitBtn.IsVisible = false;
        }
    }
这里url字符串里面的城市需要用到url编码,这里给出算法:
 public class GetUrlEncoder
    {
        public static string UrlEncode(string str, string encode)
        {
            StringBuilder sb = new StringBuilder();
            byte[] byStr = System.Text.Encoding.GetEncoding(encode).GetBytes(str); for (int i = 0; i < byStr.Length; i++)
            {
                sb.Append(@"%" + Convert.ToString(byStr[i], 16));
            }
            return (sb.ToString());
        }
    }
还有设置天气的图片,这里用到字典和静态构造,这里不好的一点是如果查到下面没有的天气情况,程序会崩溃:
class ImageTemplate
    {
        public static Dictionary<string,string> DicImage = new Dictionary<string, string>() ;
        static ImageTemplate()
        {
            DicImage.Add("暴雪", "weather_baoxueb.png" );
            DicImage.Add("暴雨", "weather_baoyub.png");
            DicImage.Add("大暴雨", "weather_dabaoyub.png");
            DicImage.Add("大雪", "weather_daxueb.png");
            DicImage.Add("大雨", "weather_dayub.png");
            DicImage.Add("多云", "weather_duoyunb.png");
            DicImage.Add("拂尘", "weather_fuchenb.png");
            DicImage.Add("雷阵雨","weather_leizhenyub.png");
            DicImage.Add("雷阵雨伴有冰雹", "weather_leizhenyubanyoubingbaob.png");
            DicImage.Add("雾霾", "weather_maib.png");
            DicImage.Add("晴", "weather_qingb.png");
            DicImage.Add("沙尘暴","weather_shachenbaob.png");
            DicImage.Add("特大暴雨", "weather_tedabaoyub.png");
            DicImage.Add("雾", "weather_wub.png");
            DicImage.Add("小雨", "weather_xiaoyub.png");
            DicImage.Add("小雪", "weather_xiaoxueb.png");
            DicImage.Add("扬沙", "weather_yangshab.png");
            DicImage.Add("阴", "weather_yinb.png");
            DicImage.Add("雨夹雪", "weather_yujiaxueb.png");
            DicImage.Add("阵雪", "weather_zhenxueb.png");
            DicImage.Add("阵雨", "weather_zhenyub.png");
            DicImage.Add("中雪","weather_zhongxueb.png");
            DicImage.Add("中雨", "weather_zhongyub.png");
            DicImage.Add("冻雨", "weather_dongyub.png");
            DicImage.Add("中到大雨","zhongdaodayu.png");
        }
    }
天气属性类:
 public class WeatherInfo
    {
        public string Days { get; set; }
        public string CityName { get; set; }
        public string TemperatureL { get; set; }
        public string Weather { get; set; }
        public string WeatherImage { get; set; }
    }
这里给出图标地址,有兴趣自己去下载: http://download.csdn.net/detail/kevinwu93/9308497
有什么问题欢迎联系博主,博主QQ:1405999864