これは何?
弊社で行った勉強会の資料を見える形にして公開したものです。
勉強会
Xamarin.Formsの勉強会です。
対象は以下のような人です。
- プログラミングをしている
- C#を触ったことがない
- Xamarinが気になる
- クロスプラットフォームアプリ開発が気になる
事前準備
- Visual Studioのインストール
- XCodeのインストール(Macの方)
もちろんしてあるよね?
してないならすぐにしよう!
インストールには結構時間かかるからね!
今日の予定
13:00 ~ 14:00
- C#とは
- Linq
- Xamarinとは
- Xamarinネイティブ
- Xamarin.Forms
14:15 ~ 15:15
- Visual Studioとは
- プロジェクトの作り方
- デバッグの仕方
- nuget
15:30 ~ 19:00
- Xamarin.Formsアプリの構成
- Pages
- Layout
- Control
- よく使うライブラリ
- Xamarin.Formsでアプリを作ろう
C#とは
C#概要
- Microsoftが開発したプログラミング言語
- 文法はC言語スタイルのよくあるやつ(CとかC++とかJavaとか)
- Linq
- Visual Studio
public string GetMyBirthday()
{
return "1991/10/03";
}
Linq
- Language INtegrated Queryの略称
- Linq使わないならC#使わないほうがいい
- いろんなデータに対して統一的な手段でアクセスする仕組み
- Linq to SQL
- Linq to XML
- Linq to Entities
- Linq to Objects
- Linq to DataSet
- ...
Linqをどう使うか
public class Employee
{
public string Name { get; set; }
public int Age { get; set; }
public int CompanyID { get; set; }
}
private int MY_COMPANY_ID = 1;
public void Main()
{
// すべての社員を取得
List<Employee> AllEmployeeList = GetAllEmployee();
// 弊社の社員を取得
List<Employee> MyCompanyEmployeeList =
AllEmployeeList.Where( x => x.CompanyID == MY_COMPANY_ID );
// 弊社の30才以下の社員の名前一覧を取得
List<string> MYCompanyEmployeeNameList =
AllEmployeeList
.Where( x => x.CompanyID == MY_COMPANY_ID && x.Age <= 30 )
.Select( x => x.Name );
}
public class SoccerPlayer : Employee
{
public string Position { get; set; }
}
public void Main()
{
var MyCompanyEmployeeList =
db.EmproyeeMaster
.Where( x => x.CompanyID == MY_COMPANY_ID )
.OrderBy( x => x.Age )
.Select( x => new SoccerPlayer
{
Name = x.Name,
Age = x.Age,
CompanyID = x.CompanyID,
FavoriteColor = "goal keeper"
});
}
Xamarinとは
- .NETの技術でiOS・Androidアプリ「とか」が作れるSDK
- 作れるもの
- iOSアプリ
- Androidアプリ
- Windowsアプリ(UWP)
- Macアプリ
- このいろいろ作れるものの総称としてXamarinと呼んでいる
- 作り方(共通化できる範囲で分けている)
- Xamarinネイティブ
- Xamarin.Forms
Xamarinネイティブ
- アプリのコア部分(サーバー側)を共通化できる
- 画面側は共通化できない
- つまりAndroidとiOSのフロント技術がそのまま使える
Xamarin.Forms
- アプリのコア部分(サーバー側)を共通化できる
- 画面側も共通化できる
- ひとつのコードで両対応の画面が生成できる!
- つまりXamarin.Formsを使えばiOSやAndroidの知識がなくても作れるということ?
- 残念ながらそんなことはない
- 出力されるものはiOSやAndroidなので、画面側で固有のバグが発生した場合に特定が難しくなる可能性
- Xamarin.FormsはiOSとAndroidの最大公約数的な作り方になっている
- 片方のみに存在するAPIが実装されていなかったりする
- この場合書き方を分ける必要があるし、それぞれのネイティブの知識がないと難しい
Visual Studioとは
Visual Studio概要
- microsoftが提供する統合開発環境
- C#の開発するならとにかくこれを使う
- 環境を整えるのが(比較的)簡単(になった)
- 今回だってVisual Studioのインストールだけで事前準備終わりだしね
- Nuget
- Visual Studioの話だけで勉強会できるぐらいいろんなことができる
- なのでざっくり話します
Visual Studioの使い方
プロジェクトの作り方
[Visual C#]→[Cross-Platform]→[Cross Platform App (Xamarin)]
[Blank App]
[Xamarin.Forms]
[Portable Class Library (PCL)]
デバッグの方法
- デバッグボタンを押すだけ
- Xamarin.Formsの場合、Androidのエミュレータが起動します
- その上で作成したアプリケーションが動きます
その前に変更しましょう!!!!!
右の「▼」を押すとリストが開くので変更しましょう。ARMはヤバイです。
どれぐらいARMヤバイの?
- 実行速度(起動速度)に10倍の差があると言われています
- 実際にこういう警告文をVisual Studioさんが出します
- 体感だとそれ以上遅いような気さえする
- とにかく遅いヤバイ
Nugetとは
- Visual Studioのパッケージ管理ツール
- [プロジェクト]→[Nugetパッケージの管理]
- いろんなパッケージを入れたり消したりできる
- ビルド時に足りないパッケージを復元してくれる
- わかりやすいので好き
Xamarin.Formsでアプリを作るには
Xamarin.Formsアプリの構成
作成時点では次のようになっている
- PCL
- Xamarin.Android
- Xamarin.iOS
- PCLがXamarin.AndroidやXamarin.iOSから参照されて画面作成等している
- 基本的に触るのはPCLのみ
- アプリが動くとApp.xaml.csがまず動く
- どれを最初に動かそうとしているかはXamarin.AndroidのMainActivity.csを見よう
InitializeComponent();
- MainPageを描画する画面として設定
Main.xaml
デバッグ実行したときに見えた「Welcome to Xamarin.Forms!」はここ
Pages
- Pagesクラスは画面のほとんどを占有する、画面の基本的なクラス
- URLを見ながら解説します
とても参考になるページ
https://dev.classmethod.jp/smartphone/xamarin-forms-page/
Layout
- Layoutクラスはページやビュー上に複数のコントロールを配置するためのコンテナ
- URLを見ながら解説します
とても参考になるページ
https://dev.classmethod.jp/smartphone/xamarin-forms-layout/
Control
- ControlクラスはPages、Layoutの上に乗せていくコントロール
- Xamarin.Formsのフレームワークの中では、「Views」と言う名前でカテゴライズされている
- URLの中からいくつかピックアップしてお話します
とても参考になるページ
https://dev.classmethod.jp/smartphone/xamarin-forms-control1/
https://dev.classmethod.jp/smartphone/xamarin-forms-controll2/
データバインディング
- Xamarin.Formsにはデータバインディングを行う機能がある
- 強力な機能なのでXamarin.Forms開発者は全員使うべき
- デモします
public class Employee : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
...
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
わざわざOnPropertyChangedの実装をしないといけない…
めんどくさい…
using PropertyChanged;
public class Employee : INotifyPropertyChanged
{
public string Name { get; set; }
...
// eventの宣言は必要
public event PropertyChangedEventHandler PropertyChanged;
/* いらない
protected virtual void OnPropertyChanged(string name)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
*/
}
PropertyChanged.Fodyを使って簡略化!!
よく使うライブラリ
- PropertyChanged.Fody
- プロパティが変更されたことを自動で通知してくれるライブラリ
- これを使わないと画面にバインドするModelの中身が結構大変なことになる
- インストールした後にFodyを最新にアップデートすること
- sqlite-net-pcl
- Xamarin.FormsでSQLiteを使いたいときはこれ
- PCL Storage
- Xamarinのファイル操作ライブラリ
- sqlite-net-pclと組み合わせることでPCL側だけでDB操作できる
- http://www.nuits.jp/entry/2016/06/27/191636
Xamarin.Formsでアプリを作ろう!
作るもの
- ドラフトタイマー
仕様
- ボタンを押してタイマースタート
- 現在何パック目かの音声出力(他、適宜必要な場所で音声を入れる)
- 現在何パック目、何ピック目かを表示しておく
- ドラフトの時間は1ピック目から順に以下の通り(単位:秒)
- { 40, 35, 30, 25, 25, 20, 20, 15, 10, 10, 5, 5, 5, 5 }
- ドラフトのパックとパックの間にはインターバルを取る
- 1回目 60秒
- 2回目 90秒
タイマーの実装に役立つもの
デバイスのタイマー機能
Device.StartTimer(Timespan interval, Func<>());
Device.StartTimer(
TimeSpan.FromSeconds(1),
() =>
{
// タイマー操作;
});
Func<>の部分でtrueを返すとTimerは継続して実行される。
falseが返されるとTimer終了。
デバイスの音声読み上げ機能
- Xamarin.Formsのデフォルトの機能として用意されていない
- Android、iOSにそれぞれの処理を書く必要がある
作る手順は以下。
- PCLにinterfaceを作成する
- Project.Androidに1.のinterfaceを継承したclassを作成する
- Project.iOSに1.のinterfaceを継承したclassを作成する
public interface ITextToSpeech
{
void Speak(string text);
}
PCLにITextToSpeech
interfaceを作成する。
[assembly: Dependency(typeof(TextToSpeechImplementation))]
namespace DraftTimeManager.Droid
{
public class TextToSpeechImplementation : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
{
private TextToSpeech speaker;
private string toSpeak;
public void Speak(string text)
{
toSpeak = text;
if (speaker == null)
{
speaker = new TextToSpeech(Forms.Context, this);
}
else
{
speaker.Speak(toSpeak, QueueMode.Flush, null, null);
}
}
public void OnInit(OperationResult status)
{
if (status.Equals(OperationResult.Success))
{
speaker.Speak(toSpeak, QueueMode.Flush, null, null);
}
}
}
}
Project.AndroidにITextToSpeech
を継承させたTextToSpeechImplementation
を作成する。
[assembly: Dependency(typeof(TextToSpeechImplementation))]
namespace DraftTimeManager.iOS
{
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation() { }
public void Speak(string text)
{
var speechSynthesizer = new AVSpeechSynthesizer();
var speechUtterance = new AVSpeechUtterance(text)
{
Rate = AVSpeechUtterance.MaximumSpeechRate / 2,
Voice = AVSpeechSynthesisVoice.FromLanguage("en-US"),
Volume = 0.5f,
PitchMultiplier = 1.0f
};
speechSynthesizer.SpeakUtterance(speechUtterance);
}
}
}
Project.iOSにITextToSpeech
を継承させたTextToSpeechImplementation
を作成する。
参考資料
https://qiita.com/amay077/items/38ee79b3e3e88cf751b9
http://furuya02.hatenablog.com/entry/20140523/1400966058
https://developer.xamarin.com/guides/xamarin-forms/getting-started/