読者です 読者をやめる 読者になる 読者になる

Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

Xamarin.Androidで画面サイズを取得するには?

Xamarin Xamarin.Android

こんにちは。エクセルソフトの田淵です。

この後シリーズで続ける予定のAccelerometer取得のサンプルを作る際に、TextVeiwLabelが画面上を動くと楽しそうだなと思いまして。そのためにはラベルをAbsoluteLayoutで配置して、画面を飛び出さないようにする必要があり。なので、画面サイズを取得するには?ですw

Androidネイティブの記事がたくさん掲載されているTECHBOOSTERさんの Androidの画面サイズを攻略して機種依存を吸収する(ナビゲーションバーとステータスバーのサイズを取得する) | TechBooster を参考にしました。ありがとうございます。

ハードウェアの画面サイズ、ディスプレイサイズの取得

http://techbooster.org/wp-content/uploads/2013/02/screensize2.png
(画像はTECHBOOSTERさんより)

この通りで、Android 4.2以上であれば、WindowManagerのDefaultDisplyから取得します。Xamarin.AndroidではActivityクラスにIWindowManagerというInterfaceが用意されていて、GetSize(Point)GetRealSize(Point)のvoidメソッドがありましたので、

Point prealsize = new Point();
WindowManager.DefaultDisplay.GetRealSize(prealsize); // ハードウェアの画面サイズ取得(4.2以降)
Log.Debug("Info", "Width(GetRealSize): " + prealsize.X);
Log.Debug("Info", "Height(GetRealSize): " + prealsize.Y);

Point psize = new Point();
WindowManager.DefaultDisplay.GetSize(psize); // ナビゲーションバー以外のディスプレイサイズ取得
Log.Debug("Info", "Width(GetSize): " + psize.X);
Log.Debug("Info", "Height(GetSize): " + psize.Y);

で取得できました。Android MをインストールしたNexus 5では、

Width(GetRealSize): 1080
Height(GetRealSize): 1920
Width(GetSize): 1080
Height(GetSize): 1776

となりました。ナビゲーションバーのサイズが144dpな事が分かります。

コンテンツ領域のサイズを取得

TECHBOOSTERさんのサイトと同じように、OnWindowFocusChangedメソッド内でコンテンツサイズを取得してみます。

public override void OnWindowFocusChanged(bool hasFocus)
{
    base.OnWindowFocusChanged(hasFocus);
    // ContentViewに配置したAbsoluteLayoutのサイズ
    Log.Debug("Info", "Width(AbsoluteLayout): " + abs.Width);
    Log.Debug("Info", "Height(AbsoluteLayout): " + abs.Height);
}

Themeをいくつか変更しながら試してみました。

Theme = "@android:style/Theme.Material.Light.NoActionBar"
Width(AbsoluteLayout): 1080
Height(AbsoluteLayout): 1704

Theme = "@android:style/Theme.Material.Light"
Width(AbsoluteLayout): 1080
Height(AbsoluteLayout): 1536

Theme = "@android:style/Theme.Holo.Light.DarkActionBar"
Width(AbsoluteLayout): 1080
Height(AbsoluteLayout): 1560

NoActionBarにするとタイトルバーが無くなるので、1776dpから1704dpを引けばステータスバーのサイズが72dpであることが分かります。Material Themeと4.x以下のHolo ThemeではタイトルバーのサイズがMaterialは168dp、Holoは144dpと異なることも分かりました。

後はコンテンツ領域のサイズを元に配置したいコントロールのサイズを指定して、AbsoluteLayoutで配置してあげればOKですね。例えば以下のような感じだとコンテンツ領域の中央に配置できます。

layoutW = abs.Width;
layoutH = abs.Height;

textView = new TextView(this);

textW = abs.Width / 2;
textH = abs.Height / 5;

if (!textView.IsShown)
    abs.AddView(textView, new AbsoluteLayout.LayoutParams(textW, textH, abs.Width / 2 - textW / 2, abs.Height / 2 - textH / 2));

(AbsoluteLayoutは旧型式です。と怒られる件については余裕があれば調べてみます)

次は iOS でやってみたいと思います。

Xamarin 気になった方は

是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の情報が欲しい方はこのブログも購読いただいたりすると嬉しいです。

以上です。