📌

getDimensionPixelOffsetとgetDimensionPixelSizeの違い

2022/08/30に公開

Androidでリソースのdimensから値を整数として取得す場合に次の2つのメソッドを利用する

  • getDimensionPixelOffset
  • getDimensionPixelSize

これらのどちらを使えば良いのか、そもそも違いはなんなのか

結論

getDimensionで取得した浮動小数の小数点の丸め方が違う

getDimensionPixelOffset

小数点を切り捨て

Float(変換前) Int(オフセット変換)
3.1 3
3.5 3
0.1 0
0.5 0

getDimensionPixelSize

小数点第1位で四捨五入した結果、0なら1を、それ以外であればその結果を返す

Float(変換前) Int(サイズ変換)
3.1 3
3.5 4
0.1 1
0.5 1

developersの定義をみる

getDimensionPixelOffset(オフセット変換)

https://developer.android.com/reference/android/content/res/Resources#getDimensionPixelOffset(int)

Retrieve a dimensional for a particular resource ID for use as an offset in raw pixels. This is the same as getDimension(int), except the returned value is converted to integer pixels for you. An offset conversion involves simply truncating the base value to an integer.

getDimension(int) と同じだが、ベース値を切り捨てた整数で返すと書いてる

getDimensionPixelSize(サイズ変換)

https://developer.android.com/reference/android/content/res/Resources#getDimensionPixelSize(int)

Retrieve a dimensional for a particular resource ID for use as a size in raw pixels. This is the same as getDimension(int), except the returned value is converted to integer pixels for use as a size. A size conversion involves rounding the base value, and ensuring that a non-zero base value is at least one pixel in size.

getDimension(int) と同じだが、基数を丸めて1以上の整数を返すと書いてる

サイズ変換は具体的にどんな計算をしているのか

サイズ変換をめちゃめちゃ簡単に説明すると次のようになっている

  1. 取得したFloatに0.5fを追加して小数点以下を切り捨てる
  2. 切り捨てた値が0ではない場合はそのまま返し、0の場合は1を返す

実際のコードは次のようになっている

public static int complexToDimensionPixelSize(int data,
        DisplayMetrics metrics)
{
    final float value = complexToFloat(data);
    final float f = applyDimension(
            (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
            value,
            metrics);
    final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
    if (res != 0) return res;
    if (value == 0) return 0;
    if (value > 0) return 1;
    return -1;
}

基本は書いてる通りだが、ポイントだけ抜粋するとこうなる

  • complexToFloat で指定された値を浮動小数として取得する
  • applyDimension でピクセル密度に対応した値にする
  • 三項演算子のところで浮動小数がマイナスだった場合にも対応させる
  • あとは順番に値を比較して返すだけ

オフセット変換はどうなっているのか

こっちは何もしないで Float.toInt() で小数点以下を切り捨てるだけ
内部的にはJavaなので (int) でキャストしてる

Discussion