はじめに
こんにちは、私が説明するのはタイトルにあるようにXamarin.AndroidでのSwitchの使い方です。私が以前Switchを使おうとした時に、Xamarin.Formsの方の解説はたくさんあるのにXamarin.Androidの解説が全くと言っていいほど無かったので書いておきます。
プログラミング環境はVisual Studio 2019です。
作ったもの
今回は使い方を知りたかったのでSwitchを切り替えると文字が変わるだけのプログラムを書きました。
このようにSwitchが左の時はOff、右の時はOnと表示されるものです。
まずはコードの前にSwitchの説明をします。
Switchについて
SwitchはOn Offなど、2つの値を切り替える時に使うものです。Android標準のアラームにも使われていますね。SwitchをUIに使いたい場合、Buttonなどと同じようにxmlまたはxamlファイルに書きます。私はxmlファイルでの書き方しか把握していないためこの記事ではxamlファイルの場合は解説できません。
xmlのコード
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Switch
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/Switch" />
</LinearLayout>
Switchを置きたい場合上図のように書けば配置できます、私は親LayoutをLinearLayoutにしていますが、適切なものを選べば他のLayoutでもできるはずです。
Switchでも横幅や高さの指定は他のものと変わらずにできidは必須です。
続いてC#のコードです。
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Switch sw = FindViewById<Switch>(Resource.Id.Switch);
sw.Click += sw_Click;
}
protected override void OnCreate(Bundle savedInstanceState)
の中の下2行を書くだけでボタンをC#で使えるようにすることができます。このコードの場合、SwitchがClickされた時にsw_Click関数(後で定義する)が実行されるようになります。
次にコード上での扱い方を説明します。
まずSwitchクラスswが上図のコードでは宣言されていますが、その中に Checked
というbool型の変数があり、Switchが左向き(初期の状態)ではfalse、右向き(初期の状態から1回押した状態)ではtrueが入っています。そのためsw内のCheckedさえ取り出すことができれば、あとは値を調べ、if文を使って値ごとの条件を書けば良いのです。取り出す方法は簡単で sw.Checked
だけです。あとはこれがtureかfalseかを調べればいいだけですので簡単ですね。では始めに載せた画像のアプリのコードを見てみましょう。
アプリのコード
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text" />
<Switch
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/Switch" />
</LinearLayout>
C#
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using System;
namespace switch_exp
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
public TextView text { get; private set; }
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
text = FindViewById<TextView>(Resource.Id.text);
Switch sw = FindViewById<Switch>(Resource.Id.Switch);
sw.Click += sw_Click;
}
private void sw_Click(object sender, EventArgs e)
{
Switch sw = FindViewById<Switch>(Resource.Id.Switch);
if(sw.Checked == true)
{
text.Text = "On";
}
else
{
text.Text = "Off";
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
protected override void OnCreate(Bundle savedInstanceState)
はTextViewが増えただけで先程とほとんど変わりません。このコードで重要なのは private void sw_Click(object sender, EventArgs e)
です。このアプリではSwitchの切り替えによって表示される文字が変化しますがそれをたったこれだけで書けてしまうのです。ifの条件式もsw.Checkedがtrueかfalseかを調べているだけで特に難しいわけでもなく、あとはifとelseそれぞれに処理を書いていけばSwitchは使えます。
ちなみにこのコードでは OnCreate
と sw_Click
両方でSwitch型のクラスswを宣言していますが、これを関数の外(public class MainActivity : AppCompatActivity
直下)に書くのはダメでしたので、今回は両方の関数で宣言しました。そのためこの2つは名前は同じですが全く別のクラスです。しかしそれぞれのクラスには全く同じSwitchが紐付けられているので問題なく動作します。
もしかしたら何か方法があるのかもしれませんができちゃったので今回はやりません。
最後に
長々と書きましたがたったこれだけです、読むと難しく感じるかもしれませんがやってみると簡単だと感じるはずなのでぜひやってみてください。
それにしてもなんでXamarin.Androidの記事は全然無いんですかね、あったらこれを調べる必要無かったのに。。。