ConstraintLayout을 사용하여 동적으로 사라진 위젯의 레이아웃 문제를 해결한 방법

이 게시물은 기본 Android 개발에서 ConstraintLayout을 사용하여 위젯GONE을 처리하는 방법에 관한 것입니다.

연구 사례



Activity 의 샌드위치 개체로 뒷받침되는 목록에서 선택한 각 샌드위치의 세부 정보를 표시하는 화면이 있습니다.

이 화면은 ConstraintLayout으로 작성되었으며 다음과 같은 정보를 표시합니다.
  • 라고도 함
  • 재료,
  • 원산지
  • 설명

  • 중요한 부분만 포함된 레이아웃은 다음과 같습니다.

    ...
    <layout ...
        >
        <ScrollView ...
            >
            <androidx.constraintlayout.widget.ConstraintLayout ...
                >
    
                <ImageView
                    ...
                    android:id="@+id/sandwich_image"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    ...
                    />
    
                <TextView
                    ...
                    android:id="@+id/also_know_as_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/sandwich_image"
                    />
    
                <TextView
                    ...
                    android:id="@+id/also_know_as_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/also_know_as_label"
                    ...
                    />
    
                <TextView
                    ...
                    android:id="@+id/ingredients_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_text"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_text"
                    app:layout_constraintTop_toBottomOf="@+id/also_know_as_text"
                    />
    
                <TextView
                    ...
                    android:id="@+id/ingredients_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/ingredients_label"
                    ...
                    />
    
                <TextView
                    ...
                    android:id="@+id/origin_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/ingredients_text"
                    />
    
                <TextView
                    ...
                    android:id="@+id/origin_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/origin_label"
                    ...
                    />
    
                <TextView
                    ...
                    android:id="@+id/description_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/origin_text"
                    />
    
                <TextView
                    ...
                    android:id="@+id/description_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_know_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_know_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/description_label"
                    ...
                    />
            </androidx.constraintlayout.widget.ConstraintLayout>
        </ScrollView>
    </layout>
    


    다음은 디자인 모드에서 위의 레이아웃을 나타낸 것입니다.



    물리적 장치에서 애플리케이션을 실행한 후 원하는 결과를 얻었습니다.



    문제



    일부 샌드위치 개체에는 일부 속성의 데이터가 부족합니다. 일반적인 솔루션은 View의 가시성을 View.GONE으로 설정하는 것입니다.

    결과는 예상하지 못했습니다.



    ConstraintLayout에서 우리는 View가 서로에 대해 제약을 받았기 때문에 결국 문제가 생겼습니다.

    해결책



    간단한 솔루션을 찾았고 답은 ConstraintLayout Barrier였습니다.

    docs에서:

    A Barrier references multiple widgets as input, and creates a virtual guideline based on the most extreme widget on the specified side. For example, a left barrier will align to the left of all the referenced views.



    실제로 방법에 대한 권장 사항이 있습니다handle GONE widgets.

    Barrier에 대해 더 깊이 들어가지는 않겠습니다. 좋은 예가 있는 this awesome explanation을 확인하십시오.

    중요한 부분만 포함된 최종 레이아웃은 다음과 같습니다.

    ...
    <layout ...
        >
        <ScrollView ...
            >
            <androidx.constraintlayout.widget.ConstraintLayout ...
                >
                <ImageView
                    ...
                    android:id="@+id/sandwich_image"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    ...
                    />
    
                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/start_guideline"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    app:layout_constraintGuide_begin="@dimen/margin_normal"
                    />
    
                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/end_guideline"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    app:layout_constraintGuide_end="@dimen/margin_normal"
                    />
    
                <TextView
                    ...
                    android:id="@+id/also_known_as_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toStartOf="@+id/end_guideline"
                    app:layout_constraintStart_toStartOf="@+id/start_guideline"
                    app:layout_constraintTop_toBottomOf="@+id/sandwich_image"
                    />
    
                <TextView
                    ...
                    android:id="@+id/also_known_as_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/also_known_as_label"
                    app:layout_constraintStart_toStartOf="@+id/also_known_as_label"
                    app:layout_constraintTop_toBottomOf="@+id/also_known_as_label"
                    ...
                    />
    
                <androidx.constraintlayout.widget.Barrier
                    android:id="@+id/also_known_as_barrier"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:barrierDirection="bottom"
                    app:constraint_referenced_ids="also_known_as_label,also_known_as_text"
                    />
    
                <TextView
                    ...
                    android:id="@+id/ingredients_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toStartOf="@+id/end_guideline"
                    app:layout_constraintStart_toStartOf="@+id/start_guideline"
                    app:layout_constraintTop_toBottomOf="@+id/also_known_as_barrier"
                    />
    
                <TextView
                    ...
                    android:id="@+id/ingredients_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/ingredients_label"
                    app:layout_constraintStart_toStartOf="@+id/ingredients_label"
                    app:layout_constraintTop_toBottomOf="@+id/ingredients_label"
                    ...
                    />
    
                <androidx.constraintlayout.widget.Barrier
                    android:id="@+id/ingredients_barrier"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:barrierDirection="bottom"
                    app:constraint_referenced_ids="ingredients_label,ingredients_text"
                    />
    
                <TextView
                    ...
                    android:id="@+id/origin_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toStartOf="@+id/end_guideline"
                    app:layout_constraintStart_toStartOf="@+id/start_guideline"
                    app:layout_constraintTop_toBottomOf="@+id/ingredients_barrier"
                    />
    
                <TextView
                    ...
                    android:id="@+id/origin_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/origin_label"
                    app:layout_constraintStart_toStartOf="@+id/origin_label"
                    app:layout_constraintTop_toBottomOf="@+id/origin_label"
                    ...
                    />
    
                <androidx.constraintlayout.widget.Barrier
                    android:id="@+id/origin_barrier"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:barrierDirection="bottom"
                    app:constraint_referenced_ids="origin_label,origin_text"
                    />
    
                <TextView
                    ...
                    android:id="@+id/description_label"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toStartOf="@+id/end_guideline"
                    app:layout_constraintStart_toStartOf="@+id/start_guideline"
                    app:layout_constraintTop_toBottomOf="@+id/origin_barrier"
                    />
    
                <TextView
                    ...
                    android:id="@+id/description_text"
                    android:layout_width="0dp"
                    app:layout_constraintEnd_toEndOf="@+id/description_label"
                    app:layout_constraintStart_toStartOf="@+id/description_label"
                    app:layout_constraintTop_toBottomOf="@+id/description_label"
                    ...
                    />
    
            </androidx.constraintlayout.widget.ConstraintLayout>
        </ScrollView>
    </layout>
    


    소스 코드는 GitHub에서 사용할 수 있습니다.

    좋은 웹페이지 즐겨찾기