주문형 뷰 로드

때때로 레이아웃에 거의 사용되지 않는 복잡한 뷰가 필요한 때가 있습니다. 세부정보, 진행률 표시기 또는 실행취소 메시지 중 무엇을 사용하든 필요할 때만 뷰를 로드하여 메모리 사용량을 줄이고 렌더링 속도를 높일 수 있습니다.

향후 앱에 필요한 복잡한 뷰가 있을 때 복잡하고 거의 사용되지 않는 뷰의 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과 같은 코드를 생성합니다.

빈 화면의 이미지
그림 1. 화면의 초기 상태: ViewStub가 과도한 레이아웃을 숨김

ViewStub에서 지정된 레이아웃을 로드하려면 setVisibility(View.VISIBLE)를 호출하여 표시되도록 설정하거나 inflate()를 호출합니다.

다음 코드 스니펫은 연기된 로드를 시뮬레이션합니다. 화면이 ActivityonCreate()에서 평소와 같이 로드되면 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);
}
그림 2. 과도한 레이아웃이 보입니다.

표시되거나 확장되고 나면 ViewStub 요소는 더 이상 뷰 계층 구조의 일부가 아닙니다. 확장된 레이아웃으로 대체되며 이 레이아웃의 루트 뷰 ID는 ViewStubandroid:inflatedId 속성으로 지정됩니다. ViewStub에 지정된 ID android:idViewStub 레이아웃이 표시되거나 확장될 때까지만 유효합니다.

이 주제에 관한 자세한 내용은 스텁으로 최적화 블로그 게시물을 참고하세요.