星期三, 6月 10, 2020

[X.Form] HttpClient 抓取 API 資料

課程上老師抓取 [開放資料平台 - 特生中心蛾調志工蛾類調查資料集],來介紹 HttpClient 抓取 API 資料,把該範例改成抓 json 來練習

透過該 網站,把抓下來的 json 格式化,方便閱讀,json 資料格式如下圖,records 是資料

[X.Form] HttpClient 抓取 API 資料-2

操作畫面呈現

[X.Form] HttpClient 抓取 API 資料-1


App.xaml.cs - 使用 NavigationPage 功能
using Xamarin.Forms;

namespace OpenSource
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new NavigationPage(new MainPage());
        }
    }
}
Model - 利用 [VS] 選擇性貼上 產生 class,並根據開放資料平台上說明把欄位說明補上
namespace OpenSource.Models
{
    public class Record
    {
        /// <summary>
        /// 標本編號
        /// </summary>
        public string MothCollectSpeciesID { get; set; }
        /// <summary>
        /// 採集日期
        /// </summary>
        public string MothCollectDate { get; set; }
        /// <summary>
        /// 縣市
        /// </summary>
        public string County { get; set; }
        /// <summary>
        /// 鄉鎮
        /// </summary>
        public string Township { get; set; }
        /// <summary>
        /// 採集地點
        /// </summary>
        public string MothCollectPlace { get; set; }
        /// <summary>
        /// 緯度(WGS84)
        /// </summary>
        public string WGS84Lat { get; set; }
        /// <summary>
        /// 經度(WGS84)
        /// </summary>
        public string WGS84Lon { get; set; }
        /// <summary>
        /// 蛾科名
        /// </summary>
        public string MothFamily { get; set; }
        /// <summary>
        /// 蛾學名
        /// </summary>
        public string MothScienceName { get; set; }
        /// <summary>
        /// 照片連結
        /// </summary>
        public string MothPhotoURL { get; set; }
    }
}
MainPage.Xaml - 利用 ListView 搭配 Grid 來進行排版
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="OpenSource.MainPage"
             Title="蛾類一覽表">

    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="Medium"/>
            <Setter Property="HorizontalTextAlignment" Value="Center"/>
            <Setter Property="VerticalTextAlignment" Value="Center"/>
        </Style>
    </ContentPage.Resources>

    <ContentPage.Content>

        <ListView 
                x:Name="MasterListView" 
                ItemsSource="{Binding Records}"
                SeparatorColor="Black" 
                VerticalOptions="StartAndExpand"
                RowHeight="100">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="2*"/>
                            </Grid.ColumnDefinitions>

                            <Image 
                                Grid.Row="0" Grid.RowSpan="2"
                                Source="{Binding MothPhotoURL}" Aspect="AspectFill"/>

                            <Label 
                                Grid.Row="0" Grid.Column="1"
                                Text="標本編號:"/>
                            <Label 
                                Grid.Row="1" Grid.Column="1"
                                Text="採集日期:"/>

                            <Label 
                                Grid.Row="0" Grid.Column="2"
                                Text="{Binding MothCollectSpeciesID}"
                                HorizontalTextAlignment="Start"/>
                            <Label 
                                Grid.Row="1" Grid.Column="2"
                                Text="{Binding MothCollectDate}"
                                HorizontalTextAlignment="Start"/>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>
MainPage.cs - 政府開放平台抓資料常常 timeout,抓兩筆資料下來方便練習
namespace OpenSource
{
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            ListViewItemSource();
            MasterListView.ItemSelected += MasterListView_ItemSelected;
        }

        private async void MasterListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            Record record = e.SelectedItem as Record;
            DetailPage page = new DetailPage(record);
            await Navigation.PushAsync(page);
        }

        #region ListView 資料來源
        public ObservableCollection<Record> Records = new ObservableCollection<Record>();

        public void ListViewItemSource()
        {
            List<Record> records = RecordParse();
            var data = records.OrderByDescending(o => o.MothCollectDate);
            foreach (var r in data)
            {
                this.Records.Add(r);
            }

            MasterListView.ItemsSource = this.Records;
            BindingContext = this.Records;
        }

        private List<Record> RecordParse()
        {
            string rawJson = DownloadOpenData();
            JObject jsonObject = JObject.Parse(rawJson);
            var records = jsonObject["result"]["records"]?.ToString();
            return JsonConvert.DeserializeObject<List<Record>>(records);
        }

        /// <summary>
        /// 政府開放平台抓資料常常 timeout,抓兩筆資料下來方便練習
        /// 可以利用該網站 http://json.parser.online.fr/ 格式化 json 資訊,方便閱讀
        /// </summary>
        /// <returns>蛾類資料 json</returns>
        private string DownloadOpenData()
        {
            string json = @"
                {
                    'success': true,
                    'result': {
                        'resource_id': '355000000I-000300',
                        'fields': [
                            {
                                'type': 'String',
                                'id': 'MothCollectSpeciesID'
                            },
                            {
                                'type': 'String',
                                'id': 'MothCollectDate'
                            },
                            {
                                'type': 'String',
                                'id': 'County'
                            },
                            {
                                'type': 'String',
                                'id': 'Township'
                            },
                            {
                                'type': 'String',
                                'id': 'MothCollectPlace'
                            },
                            {
                                'type': 'String',
                                'id': 'WGS84Lat'
                            },
                            {
                                'type': 'String',
                                'id': 'WGS84Lon'
                            },
                            {
                                'type': 'String',
                                'id': 'MothFamily'
                            },
                            {
                                'type': 'String',
                                'id': 'MothScienceName'
                            },
                            {
                                'type': 'String',
                                'id': 'MothPhotoURL'
                            }
                        ],
                        'records': [
                            {
                                'MothCollectSpeciesID': 'V35-20171110-025',
                                'MothCollectDate': '2017-11-10',
                                'County': '台北市',
                                'Township': '士林區',
                                'MothCollectPlace': '芝山文化生態綠園',
                                'WGS84Lat': '25.104055',
                                'WGS84Lon': '121.532664',
                                'MothFamily': 'Gelechiidae',
                                'MothScienceName': '',
                                'MothPhotoURL': 'https://farm5.staticflickr.com/4559/24022922357_307fae9b74.jpg'
                            },
                            {
                                'MothCollectSpeciesID': 'V35-20171110-024',
                                'MothCollectDate': '2017-11-10',
                                'County': '台北市',
                                'Township': '士林區',
                                'MothCollectPlace': '芝山文化生態綠園',
                                'WGS84Lat': '25.104055',
                                'WGS84Lon': '121.532664',
                                'MothFamily': 'Gelechiidae',
                                'MothScienceName': '',
                                'MothPhotoURL': 'https://farm5.staticflickr.com/4568/25016467528_46c6beb365.jpg'
                            }
                        ],
                        'limit': 2,
                        'offset': 2,
                        'total': 2
                    }
                }";

            return json;
        } 

        #endregion
    }
}
DetailPage.xaml - 自訂一個 Grid 來顯示詳細資料
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="OpenSource.DetailPage">

    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="Large"/>
            <Setter Property="HorizontalTextAlignment" Value="Center"/>
            <Setter Property="VerticalTextAlignment" Value="Center"/>
        </Style>
    </ContentPage.Resources>

    <ContentPage.Content>
        <Grid Margin="10,10,10,10">
            <Grid.RowDefinitions>
                <RowDefinition Height="4*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>

            <Image Grid.Row="0" Grid.ColumnSpan="2"
                Source="{Binding MothPhotoURL}"></Image>

            <Label Grid.Row="1" Grid.Column="0"
                Text="標本編號"/>
            <Label Grid.Row="1" Grid.Column="1"
                Text="{Binding MothCollectSpeciesID}"/>

            <Label Grid.Row="2" Grid.Column="0"
                Text="採集日期"/>
            <Label Grid.Row="2" Grid.Column="1"
                Text="{Binding MothCollectDate}"/>

            <Label Grid.Row="3" Grid.Column="0"
                Text="縣市"/>
            <Label Grid.Row="3" Grid.Column="1"
                Text="{Binding County}"/>

            <Label Grid.Row="4" Grid.Column="0"
                Text="鄉鎮"/>
            <Label Grid.Row="4" Grid.Column="1"
                Text="{Binding Township}"/>

            <Label Grid.Row="5" Grid.Column="0"
                Text="緯度(WGS84)"/>
            <Label Grid.Row="5" Grid.Column="1"
                Text="{Binding WGS84Lat}"/>

            <Label Grid.Row="6" Grid.Column="0"
                Text="經度(WGS84)"/>
            <Label Grid.Row="6" Grid.Column="1"
                Text="{Binding WGS84Lon}"/>

        </Grid>
    </ContentPage.Content>
</ContentPage>
DetailPage.cs - 把標本編號顯示在 Detail Title 上
namespace OpenSource
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class DetailPage : ContentPage
    {
        public DetailPage(Record record)
        {
            InitializeComponent();

            BindingContext = record;
            Title = $"{record.MothCollectSpeciesID} 明細資料";
        }
    }
}

沒有留言:

張貼留言