LoginSignup
0
3

More than 3 years have passed since last update.

【Xamarin.Forms】 グーグルマップと連携して検索を楽にする-完成版

Last updated at Posted at 2021-05-03

こんばんは。sunn-sudoです。

前回に引き続き、ユーザインターフェイスの改良を行いました。
グーグルマップのアプリと連携して、検索を楽にする個人用Androidアプリをご紹介いたします。

前回の内容は以下の記事となりますので、ご覧ください。
https://qiita.com/sunn-sudo/items/6bef0f7169b73d4e06e2

画面レイアウト

メイン画面

メイン画面.png

【ボタン】
検索ワードを追加する: 検索ワード登録画面へ遷移するボタン
【リスト内】
検索ボタン: タップしたボタンのテキストをグーグルマップに連携する
削除ボタン(✖ボタン): タップしたリストを削除する

検索ワード登録画面

検索ワード登録画面.png

【入力フォーム】
登録ボタン: 入力内容を検索ワードとして登録する。
※空文字の登録不可

ソースコード

メイン画面

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="AppGoogleMap.MainPage"
             Title="メイン画面">
    <StackLayout Margin="10">
        <Label Text="現在地周辺のスポットを検索します。" />
        <Button Text="検索ワードを追加する" Clicked="NextPage"/>
        <ListView 
        x:Name="wordList"
        HasUnevenRows="true">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout
                        HorizontalOptions="FillAndExpand"
                        Orientation="Horizontal">
                            <StackLayout 
                                Orientation="Vertical">
                                <Label Text="{Binding TimeStamp}" />
                                <Button Text="{Binding Word}" Clicked="OnButtonSearch" />
                            </StackLayout>
                            <Button
                            WidthRequest="40"
                            HeightRequest="40"
                            Text="✖"
                            BackgroundColor="Silver" 
                            VerticalOptions="Center"
                            HorizontalOptions="EndAndExpand"
                            CommandParameter="{Binding .}"
                            Clicked="OnButtonDelete"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>
MainPage.xaml.cs
using System;
using Xamarin.Essentials;
using Xamarin.Forms;
using Plugin.Geolocator;
using Plugin.Geolocator.Abstractions;
using System.Collections.ObjectModel;

namespace AppGoogleMap
{
    public class SearchWord
    {
        [SQLite.PrimaryKey, SQLite.AutoIncrement]
        public int Id { get; set; }
        public String Word { get; set; }
        public DateTime TimeStamp { get; set; }
    }

    // リスト1件のデータを表すクラス
    public class SearchWordList
    {
        public int Id { get; set; }
        public string Word { get; set; }
        public string TimeStamp { get; set; }

        public SearchWordList(int Id, string Word, string TimeStamp)
        {
            this.Id = Id;
            this.Word = Word;
            this.TimeStamp = TimeStamp;
        }
    }

    public partial class MainPage : ContentPage
    {
        public static string DbPath { get; }
            = System.IO.Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
                , "SQLiteDataBase.db");

        public static ObservableCollection<SearchWordList> WordListData { get; set; }
            = new ObservableCollection<SearchWordList>();
        public MainPage()
        {
            InitializeComponent();
            // ListViewの初期化
            WordListData = new ObservableCollection<SearchWordList>();
            // データベース初期設定
            using (var db = new SQLite.SQLiteConnection(DbPath))
            {   // テーブル作成
                db.CreateTable<SearchWord>();
                // データ取得
                foreach (var row in db.Table<SearchWord>())
                {
                    WordListData.Add(new SearchWordList(row.Id, row.Word, row.TimeStamp.ToString()));
                }
            }

            // ListViewにデータソースをセット
            wordList.ItemsSource = WordListData;
        }

        async void OnButtonSearch(object sender, EventArgs e)
        {
            if (Device.RuntimePlatform == Device.Android)
            {
                try
                {
                    IGeolocator locator = CrossGeolocator.Current;
                    // 1. 50mの精度に指定
                    // locator.DesiredAccuracy = 50;
                    Position position = await locator.GetPositionAsync();

                    string result = position.Latitude.ToString() + ',' + position.Longitude.ToString();
                    string search_text = ((Button)sender).Text;

                    await Launcher.OpenAsync("geo:" + result + "?q=" + search_text);
                }
                catch
                {
                    await DisplayAlert("確認", "位置情報をオンにしてください。", "OK");
                }

            }
        }

        private void OnButtonDelete(object sender, EventArgs e)
        {
            SearchWordList remove_list = (SearchWordList)((Button)sender).CommandParameter;
            using (var db = new SQLite.SQLiteConnection(MainPage.DbPath))
            {
                db.Delete<SearchWord>(remove_list.Id);
            }
            WordListData.Remove(remove_list);
        }

        private void NextPage(object sender, EventArgs e)
        {
            Navigation.PushAsync(new SubPage());
        }


    }
}

検索ワード登録画面

SubPage.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="AppGoogleMap.SubPage"
             Title="検索ワード登録画面">
    <StackLayout>
        <Label Text="登録する検索ワードを入力してください。" />
        <Entry x:Name="insertText" Placeholder="登録内容" MaxLength="100" />
        <Button Text="登録" Clicked="OnButtonInsert" />
    </StackLayout>
</ContentPage>
SubPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace AppGoogleMap
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class SubPage : ContentPage
    {
        public SubPage()
        {
            InitializeComponent();
        }

        private void OnButtonInsert(object sender, EventArgs e)
        {
            // 登録制限
            if (insertText.Text == null || insertText.Text == "")
            {
                // 登録成功アラート
                DisplayAlert("登録失敗", "入力文字が空です。", "OK");
                return;
            }

            DateTime temp_now = DateTime.Now;
            String temp_word = insertText.Text;
            // データ追加
            using (var db = new SQLite.SQLiteConnection(MainPage.DbPath))
            {   
                db.Insert(new SearchWord() {TimeStamp = temp_now, Word = temp_word});
                foreach (var row in db.Query<SearchWord>("select Id, Word, TimeStamp from SearchWord where ROWID = last_insert_rowid();"))
                {
                    MainPage.WordListData.Add(new SearchWordList(row.Id, row.Word, row.TimeStamp.ToString()));
                }
            }
            // 登録成功アラート
            DisplayAlert("登録成功", insertText.Text + "を登録しました。", "OK");
        }

    }
}

参考サイト

【Xamarin Forms で SQLite を使う】
https://rksoftware.hatenablog.com/entry/2018/01/01/135248

【Xamarin.Formsで画面遷移を実装】
https://rainbow-engine.com/xamarin-page-transition/

【Xamarin.Forms ListViewのデータソース更新時にUIを更新させる方法】
https://qiita.com/chooyan_eng/items/35594efea1bd5109b0f4

【Xamarinでデバイスの許可をアプリのダイアログで行う方法】
※位置情報権限を許可するために参考にした
https://intellectual-curiosity.tokyo/2020/01/09/xamarin%E3%81%A7%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%AE%E8%A8%B1%E5%8F%AF%E3%82%92%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AD%E3%82%B0%E3%81%A7%E8%A1%8C%E3%81%86/

この記事のコード

コードはGitHubで公開しております。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3