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です。

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)
【参考】レイアウト属性をダンプするメソッド
    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 ...
スポンサーリンク