BLOG

【第7回】Xamarinスマホアプリ:コピペ作成編

2021-03-12


ども!エンジニアの山本です

Xamarinを使ってスマホアプリをコピペで作る企画ですね







アプリを作製&解説を1本の動画にすると
分かりにくく感じたので 作製編解説編で分けました




動画では分割にしてコピペしていましたがミスのないように


5つのファイルをコピペすると完成出来るようになってます





完成ソースコードを用意したので
同じ名前のファイルを作成して
それぞれのファイルに下記のコードを貼りつけてください



①MainPage.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="XamarinWeatherApp.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="labelStyle" 
                   TargetType="Label">
                <Setter Property="FontSize" 
                        Value="Small" />
                <Setter Property="TextColor" 
                        Value="Gray" />
            </Style>

            <Style x:Key="labelResultStyle" 
                   TargetType="Label">
                <Setter Property="FontSize" 
                        Value="Medium" />
                <Setter Property="Margin" 
                        Value="10,0,0,0" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <Grid BackgroundColor="#545454" 
              Padding="10,10,10,20">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Label Text="Xamarinお天気アプリ" 
                   Grid.ColumnSpan="3"
                   HorizontalOptions="Center"
                   TextColor="White" 
                   FontAttributes="Bold" 
                   FontSize="Medium" />

            <Entry Text="Tokyo" 
                   x:Name="_cityEntry"
                   Margin="5,0"
                   VerticalOptions="Center"
                   BackgroundColor="DarkGray"
                   TextColor="White"
                   Keyboard="Default"
                   Grid.Row="1" 
                   Grid.Column="1"/>

            <Button Text="検索"
                    BorderWidth="1"
                    BorderColor="White"
                    BackgroundColor="#ff7d66"
                    TextColor="White"
                    Grid.Row="1" 
                    Grid.Column="2"
                    Clicked="OnGetWeatherButtonClicked"/>
        </Grid>

        <ScrollView>
            <StackLayout Padding="10,0,10,10" BackgroundColor="#00ffff">
                <Image Source="{Binding list[0].weather[0].icon_url}"/>
                <Grid BackgroundColor="#ccffff"  Padding="10,0,10,10" Grid.Row="1" Grid.Column="1">

                    <Label Text="時間" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="1"/>
                    <Label Text="{Binding list[0].dt_txt}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="2"/>
                    <Label Text="地域" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="3"/>
                    <Label Text="{Binding city.name}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="4"/>
                    <Label Text="温度" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="5"/>
                    <Label Text="{Binding list[0].main.temp}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="6"/>
                    <Label Text="天気" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="7"/>
                    <Label Text="{Binding list[0].weather[0].description}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="8"/>
                </Grid>

                <Image Source="{Binding list[1].weather[0].icon_url}"/>
                <Grid BackgroundColor="#ccffff" Padding="10,0,10,10" Grid.Row="1" Grid.Column="2">

                    <Label Text="時間" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="1"/>
                    <Label Text="{Binding list[1].dt_txt}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="2"/>
                    <Label Text="地域" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="3"/>
                    <Label Text="{Binding city.name}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="4"/>
                    <Label Text="温度" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="5"/>
                    <Label Text="{Binding list[1].main.temp}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="6"/>
                    <Label Text="天気" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="7"/>
                    <Label Text="{Binding list[1].weather[0].description}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="8"/>
                </Grid>

                <Image Source="{Binding list[1].weather[0].icon_url}"/>
                <Grid BackgroundColor="#ccffff"  Padding="10,0,10,10" Grid.Row="1" Grid.Column="3">

                    <Label Text="時間" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="1"/>
                    <Label Text="{Binding list[2].dt_txt}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="2"/>
                    <Label Text="地域" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="3"/>
                    <Label Text="{Binding city.name}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="4"/>
                    <Label Text="温度" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="5"/>
                    <Label Text="{Binding list[2].main.temp}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="6"/>
                    <Label Text="天気" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="7"/>
                    <Label Text="{Binding list[2].weather[0].description}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="8"/>
                </Grid>

                <Image Source="{Binding list[3].weather[0].icon_url}"/>
                <Grid BackgroundColor="#ccffff" Padding="10,0,10,10"  Grid.Row="1" Grid.Column="4">

                    <Label Text="時間" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="1"/>
                    <Label Text="{Binding list[3].dt_txt}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="2"/>
                    <Label Text="地域" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="3"/>
                    <Label Text="{Binding city.name}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="4"/>
                    <Label Text="温度" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="5"/>
                    <Label Text="{Binding list[3].main.temp}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="6"/>
                    <Label Text="天気" 
                           Style="{StaticResource labelStyle}"
                           Grid.Row="7"/>
                    <Label Text="{Binding list[3].weather[0].description}"
                           Style="{StaticResource labelResultStyle}"
                           Grid.Row="8"/>
                </Grid>
            </StackLayout>
        </ScrollView>

    </StackLayout>
</ContentPage>


②WeatherAPI.cs
namespace XamarinWeatherApp
{
    public static class Constants
    {
        public static string OpenWeatherMapForecast = "https://api.openweathermap.org/data/2.5/forecast"; 
        public static string OpenWeatherMapAPIKey = "お天気APIキー";                   
    }
}


③WeatherData.cs
using System.Collections.Generic;


namespace XamarinWeatherApp.WeatherData
{
    
    public class Main
    {
        public double temp { get; set; }
        public double feels_like { get; set; }
        public double temp_min { get; set; }
        public double temp_max { get; set; }
        public int pressure { get; set; }
        public int sea_level { get; set; }
        public int grnd_level { get; set; }
        public int humidity { get; set; }
        public double temp_kf { get; set; }
    }

    public class Weather
    {
        public int id { get; set; }
        public string main { get; set; }
        public string description { get; set; }
        public string icon { get; set; }
        public string icon_url => string.Format("{0}{1}{2}", "https://openweathermap.org/img/wn/", icon, "@4x.png");
    }

    public class Clouds
    {
        public int all { get; set; }
    }

    public class Wind
    {
        public double speed { get; set; }
        public int deg { get; set; }
    }

    public class Sys
    {
        public string pod { get; set; }
    }

    public class Rain
    {
        public double _3h { get; set; }
    }

    public class List
    {
        public int dt { get; set; }
        public Main main { get; set; }
        public List<Weather> weather { get; set; }
        public Clouds clouds { get; set; }
        public Wind wind { get; set; }
        public int visibility { get; set; }
        public double pop { get; set; }
        public Sys sys { get; set; }
        public string dt_txt { get; set; }
        public Rain rain { get; set; }
    }

    public class Coord
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class City
    {
        public int id { get; set; }
        public string name { get; set; }
        public Coord coord { get; set; }
        public string country { get; set; }
        public int population { get; set; }
        public int timezone { get; set; }
        public int sunrise { get; set; }
        public int sunset { get; set; }
    }

    public class Root
    {
        public string cod { get; set; }
        public int message { get; set; }
        public int cnt { get; set; }
        public List<List> list { get; set; }
        public City city { get; set; }
    }


}


④JsonConvert.cs
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace XamarinWeatherApp
{
    public class WeatherAPI
    {
        HttpClient _client;

        public WeatherAPI()
        {
            _client = new HttpClient();                                                           
        }


        public async Task<WeatherData.Root> GetWeatherDataList(string query)           
        {
            WeatherData.Root weatherDataList = null;                       
            try
            {
                var response = await _client.GetAsync(query);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    weatherDataList = JsonConvert.DeserializeObject<WeatherData.Root>(content);   
                }
            }

            catch (Exception ex)
            {
                Debug.WriteLine("\t\tERROR {0}", ex.Message);                   
            }

            return weatherDataList;

        }
    }
}


⑤MainPage.xaml.cs
using System;
using Xamarin.Forms;

namespace XamarinWeatherApp
{
    public partial class MainPage : ContentPage
    {
        WeatherAPI _restService;

        public MainPage()
        {
            InitializeComponent();
            _restService = new WeatherAPI();
        }

        async void OnGetWeatherButtonClicked(object sender, EventArgs e) 
        {

            if (!string.IsNullOrWhiteSpace(_cityEntry.Text)) //もし_cityEntry.Textが「空白」「空文字」だったときにデータを紐づけて!        
            {
                WeatherData.Root weatherDataList = await _restService.GetWeatherDataList(GenerateRequestUriList(Constants.OpenWeatherMapForecast));
                BindingContext = weatherDataList;
            }


            string GenerateRequestUriList(string endpoint)          
            {
                string requestUri = endpoint;
                requestUri += $"?q={_cityEntry.Text}";            
                requestUri += $"&appid={Constants.OpenWeatherMapAPIKey}";  
                requestUri += "&units=metric";                             
                requestUri += "&lang=ja";                  
                requestUri += "&cnt=8";                   

                return requestUri;
            }

        }
    }
}



コードが動かない方!
WeatherAPI.csのお天気APIコードにご自身のキーを入力してください!


プログラミング作って実践!ロックシステムアカデミー
大阪福島にあるプログラミングスクール「ロックシステムアカデミー」です!「プログラミング作って実践」をテーマに楽しく分かりやすいアプリ開発のレクチャー動画をアップしていきます! チャンネル登録よろしくお願いします! プログラミングスクール ▼「ロックシステムアカデミー」WEBサイト https://rocksystem.co.jp/academy/
https://www.youtube.com/channel/UC6JxNQ2QTX8Dl96V2MMNP8A

株式会社ロックシステム

「ブラック企業をやっつけろ!!」を企業理念にエンジニアが働きやすい環境をつきつめる大阪のシステム開発会社。2014年会社設立以来、残業時間ほぼゼロを達成し、高い従業員還元率でエンジニアファーストな会社としてIT業界に蔓延るブラックなイメージをホワイトに変えられる起爆剤となるべく日々活動中!絶賛エンジニア募集中。