LoginSignup
16

More than 5 years have passed since last update.

コンテンツルートのViewは全然ルートじゃない話

Posted at

概要

Androidアプリの開発をはじめたばかりの人にサラッと読んでもらいたい読み物です。

Design Support LibraryのSnackbarを使う際、引数にコンテンツルートを指定することがあるので振り返りに書いてみました。

実演

簡単なサンプルを実装

以下のような『Hello World!』を出力するだけのActivityを作成します。
今回のサンプルは AppCompatActivity を継承しています。

SampleActivity.java
public class SampleActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppCompatTextView textView = new AppCompatTextView(getApplicationContext());
        textView.setText("Hello World!");
        textView.setGravity(Gravity.CENTER);
        setContentView(textView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    }
}

dumpsysしてみる

SampleActivityをAndroid 5.1の端末(Nexus 5)で開いている状態で $adb shell dumpsys activity top のコマンドを実行してみると以下のView階層が出力されます。
これが実際に作られているViewです。

com.android.internal.policy.impl.PhoneWindow$DecorView{3f91dc03 V.E..... ... 0,0-1080,1920}
  android.widget.LinearLayout{2f75c780 V.E..... ... 0,0-1080,1776}
    android.view.ViewStub{24ef21b9 G.E..... ... 0,0-0,0 #1020373}
    android.widget.FrameLayout{242de9fe V.E..... ... 0,75-1080,1776}
      android.support.v7.internal.widget.FitWindowsLinearLayout{1d4c355f V.E..... ... 0,0-1080,1701 #7f0e006e app:id/action_bar_root}
        android.support.v7.internal.widget.ViewStubCompat{182fdbac G.E..... ... 0,0-0,0 #7f0e006f app:id/action_mode_bar_stub}
        android.support.v7.internal.widget.ContentFrameLayout{34572075 V.E..... ... 0,0-1080,1701 #1020002 android:id/content}
          android.support.v7.widget.AppCompatTextView{247aa80a V.ED.... ... 0,0-1080,1701}
  android.view.View{2928c87b V.ED.... ... 0,0-1080,75 #102002f android:id/statusBarBackground}
  android.view.View{3d950698 V.ED.... ... 0,1776-1080,1920 #1020030 android:id/navigationBarBackground}

ContentFrameLayout がコンテンツルートにあたるViewですが、見ての通りに全然ルートじゃありません。

もしコンテンツルートにアクセスしたいなら

以下のように実体化するのが一番に手っ取り早い方法です。

ViewGroup contentsRoot = (ViewGroup) findViewById(android.R.id.content);

最後に

今回はAndroid 5.1の端末(Nexus 5)でAppCompatActivityを継承したActivityを開いている状態でdumpsysを行いましたが、OSのバージョンやActivityの種類で異なる形のView階層ができあがるのでいろいろと試してみると面白いですよ。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16