2013 年 11 月 8 日

ウィジェットのセル数が異なってしまうとき

3087-logo

今のところ、iphoneにはなくてandroidに存在する機能の一つであるウィジェットは便利なものです。ホーム画面が散らかるとはいえ、利用次第で操作性が向上します。

ウィジェットを配置するとき、1×1,4×1などの表記がありますが、ウィジェットの幅や高さはセル単位で示されています。開発時はセル数ではなく、決められた計算式でdipという単位で指定します。

しかし、API Level14からこの計算式が大きく変更されたことで、想定したウィジェットセル数が正しく認識されないという問題があるようです。アプリが動作するOSのバージョンにより、セル数が変わってしまい、ウィジェットが配置できない場合もあります。こんなときの対処方法をまとめておきたいと思います。

セルの旧計算式

ウィジェットの定義はxmlにより行いますが、そのとき以下のような情報を指定します。

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:initialLayout="@layout/widget"
  android:minHeight="72dip"
  android:minWidth="294dip"
  android:layout_margin="0dp"
  android:padding="0dp"
  android:previewImage="@drawable/widget_preview"
  android:updatePeriodMillis="0">
</appwidget-provider>

minWidth,minHeightにて、最小幅と最小高を指定しますが、この大きさからウィジェットのセル数が求められます。

旧計算式では以下のように求めます。今、4(幅)x1(高さ)のウィジェットを定義したい場合は、以下のように求めます。

minWidth  = 74 × 4 - 2 = 294dp
minHeight = 74 × 1 - 2 = 72dp

これはあくまでも目安として考えておくほうがよいようです。

セルの新計算式

App Widget Design Guidelines

しかし、API Level14の新しい計算式では、以下のように計算します。

minWidth  = 70 × 4 − 30 = 250dp
minHeight = 70 × 1 − 30 = 40dp

以前の式の値で、4×1だったものは、5×2と認識されて、ウィジェットがおけなくなったりします。特にホーム画面をランドスケープにできる機種(4.x)で、ランドスケープにされたときに、この新しい計算式が適用されているように思えます。

しかし、API Level14未満でも動作させようと思うと、新しい式に移行することもできず困ってしまいます。
もし、そうしたい場合は、アプリのtargetSdkVersionを落としておくしかないと思います。targetSdkVersionが14以上だと、この新しい式の適用とともに、ウィジェットにパディングが加えられるようで、このパディング量も問題なのではと考えています。
先ほどのリソースから引用しておきます。

Adding margins to your app widget

As previously mentioned, Android 4.0 will automatically add small, standard margins to each edge of widgets on the Home screen, for applications that specify a targetSdkVersion of 14 or greater. This helps to visually balance the Home screen, and thus we recommend that you do not add any extra margins outside of your app widget’s background shape in Android 4.0.

targetSdkVersionは基本的にアプリがどのAPIレベルまでサポートしているかを示すものですが、上位互換を保証するためのスウィッチにもなっています(以下のリソースのandroid:targetSdkVersionところを参照)。

uses-sdk

if the API level of the platform is higher than the version declared by your app’s targetSdkVersion, the system may enable compatibility behaviors to ensure that your app continues to work the way you expect.

この場合、14未満にすることで、以前の計算式の適用が保証されることになるようです。上位互換をアプリケーションで対応せずに幅広いOSバージョンで動作させることが必要なら、targetSdkVersionを適切な値に指定してしておくほうがよいでしょう。