System Bar:Viewの構成と重ね合わせ

投稿日:  更新日:

System Barはプログラマ側で記述をしなくても、デフォルトでアプリケーション画面に表示されます。

何処かで表示されるような構成になっているのです。

System Barが表示される仕組みを調べたので紹介します。

スポンサーリンク

System Barとは

Status BarとNavigation Barの2つを合わせてSystem Barと言います。

System Barとは

Status Barは端末の通知(Notification)をアイコンで表示する上部の帯です。

Navigation barはBack・Home・Recentボタンを有する下部の帯です。

スポンサーリンク

DecorViewはView階層のルート

アプリケーションの画面を構成するViewは階層構造になっています。

その階層構造の起点(ルート:根本)になっているのがDecorViewです。

System BarまわりのView階層

DecorViewのさらに上部にViewRootImplがありますが、Viewを継承していません。なのでViewの機能を有する起点はDecorViewです。

スポンサーリンク

DecorViewは3つの子Viewを持つ

DecorViewはFrameLayoutを継承したコンテナタイプのViewです。

DecorView.javaより抜粋
1
2
3
4
5
6
public class DecorView
    extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
     
    ...
     
}

内部に3つの子Viewを持っています。この内の2つがStatus BarとNavigation Barです。

[0]LinearLayout
[1]View
[2]View
… アプリのコンテンツが格納される
… Navigation Bar
… Status Bar
※[ ]内は子Viewのインデックス番号

FrameLayoutは子Viewをインデックス番号順に重ねて表示します。

スポンサーリンク

DecorViewは3つの子Viewを重ねる

3つの子Viewを重ねる様子は、子Viewのレイアウト属性を調べれば理解できます。

【3つの子Viewを重ねる】

SYSTEM_UI_FLAG無し
※LTRB : Left,Top,Right,Bottom
【子Viewのレイアウト属性】

Class = DecorView
  Class = LinearLayout(Contents)
    Position = (0, 0)
    Size     = 320x432
    Layout Width, Height = -1,-1
    Layout Margin LTRB   = 0,0,0,48
    Layout Gravity       = -1
    Padding LTRB         = 0,24,0,0
    Visibility           = 0(Visible)
  Class = View(Navigation)
    Position = (0, 432)
    Size     = 320x48
    Layout Width, Height = -1,48
    Layout Margin LTRB   = 0,0,0,0
    Layout Gravity       = 80(Bottom)
    Padding LTRB         = 0,0,0,0
    Visibility           = 0(Visible)
  Class = View(Status)
    Position = (0, 0)
    Size     = 320x24
    Layout Width, Height = -1,24
    Layout Margin LTRB   = 0,0,0,0
    Layout Gravity       = 48(Top)
    Padding LTRB         = 0,0,0,0
    Visibility           = 0(Visible)
【参考】レイアウト属性をダンプするメソッド
レイアウト属性をダンプするメソッド
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
fun dumpViewStructure(view: View) {
    val _parent = view.parent
    if(_parent is ViewGroup) {
        Log.i(TAG, "Class = ${_parent.javaClass.simpleName}")
        _parent.forEachIndexed { index, view ->
            Log.i(TAG, "  Class = ${view.javaClass.simpleName}")
            val _XY = IntArray(2)
            view.getLocationInWindow(_XY)
            Log.i(TAG, "    Position = (${_XY[0]}, ${_XY[1]})")
            Log.i(TAG, "    Size     = ${view.width}x${view.height}")
            if(_parent is FrameLayout) {
                val _params = view.layoutParams as FrameLayout.LayoutParams
                // MATCH_PARENT -> -1, WRAP_CONTENT -> -2
                Log.i(TAG, "    Layout Width, Height = %d,%d".format(
                        _params.width,
                        _params.height
                    ))
                Log.i(TAG, "    Layout Margin LTRB   = %d,%d,%d,%d".format(
                        _params.leftMargin,
                        _params.topMargin,
                        _params.rightMargin,
                        _params.bottomMargin
                    ))
                // BOTTOM -> 80, TOP -> 48
                Log.i(TAG, "    Layout Gravity       = %d".format(
                        _params.gravity
                    ))
            }
            Log.i(TAG, "    Padding LTRB         = %d,%d,%d,%d".format(
                    view.paddingLeft,
                    view.paddingTop,
                    view.paddingRight,
                    view.paddingBottom
                ))
            // VISIBLE   -> 0, INVISIBLE -> 4, GONE -> 8
            Log.i(TAG, "    Visibility           = %d".format(
                view.visibility
            ))
        }
        dumpViewStructure(_parent)
    }
}

layout_marginとpaddingとgravityを使って、下図のように各々のViewの表示領域が区分けされています。この区分けにより、子Viewは互いに重なり合わない配置が出来ています。

System Barの重ね合わせ

スポンサーリンク

関連記事:

アプリケーションの種類によってはSystem Barを非表示にしたい場合があります。 例えば、没入したいゲームはStatus Barを非表示にして、システムからの割り込みを無くすことが望ましいでしょう。 System Barはデフォルトでアプリに表示されますが、プログラムで非表示にすることも可能です。 System Barの表示・非表示の制御について紹介します。 ...
アプリケーションの種類によってはSystem Barを非表示にしたい場合があります。 例えば、没入したいゲームはStatus Barを非表示にして、システムからの割り込みを無くすことが望ましいでしょう。 System Barはデフォルトでアプリに表示されますが、プログラムで非表示にすることも可能です。 System Barの表示・非表示の制御について紹介します。 ...
フルスクリーン(全画面モード)でコンテンツを提供することに適したアプリケーションがあります。 例えば、動画プレーヤー、ゲーム、電子書籍リーダ、画像エディター、スライドショーなどです。 アンドロイドはフルスクリーンを3つのモードに分類しています。 ...
エッジ―ツーエッジ(EdgeToEdge)について、まとめます。 エッジ―ツーエッジは言葉の通りに解釈すれば「端から端まで」ですから、見た目はフルスクリーンです。 しかし、新たな画面構成であり、フルスクリーンとは別物と定義されています。 最近は、様々なスクリーン形状を持つ端末が登場しています。 それらで、マルチウィンドウを実現するために、エッジツーエッジの対応が必須の条件になるようです。APIがエッジツーエッジを前提に作られているためです。 ですので、エッジ―ツーエッジは、今後のアプリ開発で重要な技術要素と言えます。 ※マルチウィンドウ:分割画面、フリーフォーム、PinP ※環境:Android Studio Jellyfish | 2023.3.1 Patch 1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.appcompat:appcompat 1.6.1 ...
スポンサーリンク