レイアウトによっては、ほとんど使用されない複雑なビューが必要になる場合があります。アイテムの詳細、進行状況インジケーター、元に戻すメッセージのいずれであっても、必要なときにのみビューを読み込むことで、メモリ使用量を削減し、レンダリングを高速化できます。
複雑でほとんど使用されないビューに ViewStub
を定義することで、今後アプリで必要とする複雑なビューがある場合に、リソースの読み込みを遅らせることができます。
ViewStub を定義する
ディメンションのない軽量なビューである ViewStub
は、描画を行わないか、またはレイアウトに関与しません。そのため、インフレートしてビュー階層に残すリソースはごくわずかです。各 ViewStub
には android:layout
属性が含まれ、インフレートするレイアウトを指定します。
アプリのユーザー ジャーニーの後半で読み込むレイアウトがあるとします。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:src="@drawable/logo" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
読み込みを延期するには、次の ViewStub
を使用します。表示または読み込みを行うには、参照レイアウトを表示する必要があります。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent"> <ViewStub android:id="@+id/stub_import" android:inflatedId="@+id/panel_import" android:layout="@layout/heavy_layout_we_want_to_postpone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" /> </FrameLayout>
ViewStub レイアウトを読み込む
前のセクションのコード スニペットは、図 1 のようになります。
ViewStub
で指定されたレイアウトを読み込む場合は、setVisibility(View.VISIBLE)
を呼び出して表示するように設定するか、inflate()
を呼び出します。
次のコード スニペットは、読み込みの延期をシミュレートします。Activity
と onCreate()
で画面が通常どおりに読み込まれ、heavy_layout_we_want_to_postpone
レイアウトが表示されます。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_old_xml) Handler(Looper.getMainLooper()) .postDelayed({ findViewById<View>(R.id.stub_import).visibility = View.VISIBLE // Or val importPanel: View = findViewById<ViewStub>(R.id.stub_import).inflate() }, 2000) }
Java
@Override void onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_old_xml); Handler(Looper.getMainLooper()) .postDelayed({ findViewById<View>(R.id.stub_import).visibility = View.VISIBLE // Or val importPanel: View = findViewById<ViewStub>(R.id.stub_import).inflate() }, 2000); }
可視化またはインフレートされると、ViewStub
要素はビュー階層の一部ではなくなり、インフレートされたレイアウトに置き換えられます。このレイアウトのルートビューの ID は ViewStub
の android:inflatedId
属性で指定します。ViewStub
に指定された ID android:id
は、ViewStub
レイアウトが可視化またはインフレートされるまでのみ有効です。
このトピックの詳細については、ブログ投稿 Optimize with stubs をご覧ください。