アプリの画面サイズを取得したい場合があります。タブレットとスマホで表示を変えたい
あるいはテキストの位置を正確に表示したいなど
画面サイズは getWindowInsets() を使って取得します
2024.1.1
Screen size
API29まで画面サイズを取得するには以下のようにしていましたが、これが非推奨になりました。
getDefaultDisplay()
1 2 3 4 5 6 7 8 |
WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE); Display disp = wm.getDefaultDisplay(); Point realSize = new Point(); disp.getRealSize(realSize); int ScreenWidth = realSize.x; int ScreenHeight = realSize.y; |
API30からは getWindowInsets() を使います
これを使って、Status barとNavigation bar も調べられます
1 2 3 4 5 6 7 8 |
WindowMetrics windowMetrics = this.getWindowManager().getCurrentWindowMetrics(); Insets insets = windowMetrics.getWindowInsets() .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()); int ScreenWidth = windowMetrics.getBounds().width(); int ScreenHeight = windowMetrics.getBounds().height(); int StatusBar = insets.top; int NavigationBar = insets.bottom; |
landscapeの場合はtop, bottomがleft, rightになる
WindowMetrics
ウィンドウやディスプレイのメトリクス(寸法やその他の関連情報)を取得するために使用されるクラス
Insets
Viewの内側にある空白領域を指し、コンテンツが表示されるエリアを調べられる
getWindowInsets
Androidでウィンドウのインセット情報を取得するために使用されるメソッド
getInsetsIgnoringVisibility
可視性に関係なくインセットのサイズを取得するメソッドで、システムUI要素(status bar, navigation bar など)が表示されているかどうかに関係なく、その領域のサイズがわかる
サンプルテストコード
getWindowInsets()
を使ってサイズを計測してみましょう
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
//package com.example.testscreensize; import android.os.Bundle; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import android.util.Log; import android.view.WindowInsets; import android.view.WindowMetrics; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); float dp = getResources().getDisplayMetrics().density; Log.d("log","dp="+dp); WindowMetrics windowMetrics = this.getWindowManager().getCurrentWindowMetrics(); android.graphics.Insets insets = windowMetrics.getWindowInsets() .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()); int ScreenWidth = windowMetrics.getBounds().width(); int ScreenHeight = windowMetrics.getBounds().height(); int StatusBar = insets.top; int NavigationBar = insets.bottom; Log.d("log","ScreenWidth="+ScreenWidth); Log.d("log","ScreenWidth_dp="+ScreenWidth/dp); Log.d("log","ScreenHeight="+ScreenHeight); Log.d("log","ScreenHeight_dp="+ScreenHeight/dp); Log.d("log","StatusBar="+StatusBar); Log.d("log","StatusBar_dp="+StatusBar/dp); Log.d("log","NavigationBar="+NavigationBar); Log.d("log","NavigationBar_dp="+NavigationBar/dp); } } |
エミュレータはPixel 8
Logcatでログを見てみます
1 2 3 4 5 6 7 8 9 |
dp=2.625 ScreenWidth=1080 ScreenWidth_dp=411.42856 ScreenHeight=2400 ScreenHeight_dp=914.2857 StatusBar=63 StatusBar_dp=24.0 NavigationBar=63 NavigationBar_dp=24.0 |
解像度は
1080 x 2400
とわかります
Status bar/Title bar/Navigation bar
Title bar はもう使わないような感じですがあえて計測してみます
デフォルトでactivity_main.xmlにidが振られているのでそれを使ってレイアウトの縦横サイズを取得します。ただし、これはonCreate()のタイミングでは取れないのでfocusが変わったことろで取り出します。
また、EdgeToEdge は全画面をアプリが使えるようにしているので
EdgeToEdgeがはコメントアウトします
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
... // EdgeToEdge.enable(this); ... @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); ConstraintLayout layout = findViewById(R.id.main); int layoutWidth = layout.getWidth(); int layoutHeight = layout.getHeight(); Log.d("log","layoutWidth="+layoutWidth); Log.d("log","layoutHeight="+layoutHeight); } |
Logcat には
1 2 |
layoutWidth=1080 layoutHeight=2274 |
2400 – 2274 = 126(48dp)
これは、
Satatus bar(24dp)
Navigation bar(24dp)
を除いた分が
レイアウトエリアとなっているということです
Title barを表示させるにはThemeを変更します
res¥values¥themes
themes.xml
1 2 3 4 |
... <!-- Base application theme. --> <style name="Base.Theme.TestScreenSize" parent="Theme.Material3.DayNight.NoActionBar"> ... |
NoActionBar をはずします
1 2 3 4 |
... <!-- Base application theme. --> <style name="Base.Theme.TestScreenSize" parent="Theme.Material3.DayNight"> ... |
Logcat には
1 2 |
layoutWidth=1080 layoutHeight=2106 |
Title bar は以下の計算からわかります
2274 – 2016 = 168(64dp)
Pixel8 ではこうなります
Pixel 8 | |
dip scale | 2.625 |
Resolution(dp) | 1080 x 2400 |
Aspect Ratio | 9 : 20 |
Size | 6.2″ |
Status bar | 63(24dp) |
Title bar | 168(64dp) |
Navigation bar | 63(24dp) |
References:
WindowInsets | Android Developers
WindowMetrics | Android デベロッパー | Android Developers
Display
DisplayMetrics