안녕하세요!
오늘은 안드로이드 뷰 구성에 사용되는 ConstraintLayout을 사용하면서 제가 헤맸던 부분을 소개시켜 드리고자 합니다🤗
ConstraintLayout에서 chain 이라는 제약이 있습니다. 이 제약을 이용하면 여러 개의 뷰를 그룹화하여 그룹 채로 컨트롤하는데 도움을 주기 때문에 사용하는 경우가 종종 나타나곤 합니다.
제가 개발했던 상황 역시 두개의 TextView의 그룹화가 필요했기 때문에, chain 제약의 packed을 속성을 이용해 그룹화 시켜주었습니다. 추가적으로 첫번째 TextView는 너비가 유동적으로 변할 수 있어야 했고, 두번째 TextView는 첫번째 TextView의 너비와 상관없이 chain을 유지한채 뷰가 밀리지 않아야하는 조건이 있었습니다.
당시 처음에 제가 작성한 코드는 아래와 같았습니다.
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginBottom="2dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@{data.title}"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/tv_score"
app:layout_constraintEnd_toStartOf="@id/tv_up"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/iv_thumbnail"
app:layout_constraintTop_toTopOf="@id/iv_thumbnail"
app:layout_constraintVertical_chainStyle="packed"
tools:text="제목" />
<TextView
android:id="@+id/tv_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:background="@drawable/bg_up"
android:paddingHorizontal="5dp"
android:paddingVertical="1dp"
android:text="@string/label_up"
android:textColor="@color/red"
android:textSize="8sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_title"
app:layout_constraintTop_toTopOf="@id/tv_title" />
app:layout_constraintHorizontal_chainStyle="packed"과 app:layout_constraintHorizontal_bias="0" 속성을 통해 왼쪽 정렬을 유지한 chain 제약을 주었습니다.
결과는 정상적으로 나오나 싶었으나, 첫번째 TextView의 text의 너비가 넓어지는 경우에 문제가 생겼습니다..😨
첫번째 TextView의 경우 maxLine을 1로 두었으며, 범위를 넘어간 경우에는 ellipsize를 이용해 줄임표시를 해주었습니다.
첫번째 TextView의 너비가 늘어나다 범위가 넘어간 경우에도 두번째 TextView는 밀리지않고 고정되면서, 첫번째 TextView의 text에는 줄임표시가 나타나야하지만, 결과는 두번째 TextView가 보이지않는 위치로 계속 밀리는 문제가 발생했습니다.
구글 서칭을 통해 해결방법을 찾아보니, 간단하게도 하나의 속성 추가로 해결할 수 있었습니다!
그 속성은 아래와 같습니다.
app:layout_constrainedWidth="true"
layout_constrainedWidth를 "true" 설정하면 제약 조건에 맞게 뷰가 밀리지 않도록 해줍니다.
이를 이용해서 간단하게 제가 원하는 결과를 낼 수 있었습니다.
수정된 코드 및 결과는 아래와 같습니다.
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginBottom="2dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@{data.title}"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@id/tv_score"
app:layout_constraintEnd_toStartOf="@id/tv_up"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/iv_thumbnail"
app:layout_constraintTop_toTopOf="@id/iv_thumbnail"
app:layout_constraintVertical_chainStyle="packed"
tools:text="제목제목제목제목제목제목제목제목제목제목제목제목제목제목제목제목제목제목제목제목" />
<TextView
android:id="@+id/tv_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:background="@drawable/bg_up"
android:paddingHorizontal="5dp"
android:paddingVertical="1dp"
android:text="@string/label_up"
android:textColor="@color/red"
android:textSize="8sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_title"
app:layout_constraintTop_toTopOf="@id/tv_title" />
뷰가 복잡해질 수록 뷰 계층은 깊어지고 이는 곧 성능과도 연결되는 문제이므로, 개발자는 항상 효율적인 뷰 구성을 위해 노력합니다. LinearLayout이나 RelativeLayout 등 오래 전부터 사용되는 뷰 구조가 있으나, 제약을 통해 뷰 계층의 깊이를 줄여주는 ConstraintLayout의 등장으로 간단한 뷰 구성이 가능해졌습니다.
저도 최근에 뷰를 구성함에 있어서는 ConstraintLayout을 최대한 이용하도록 노력하고 있었는데,
역시나 기능이 다양한 만큼이나 제가 모르는 사실들도 많았던 것 같습니다😭
오늘 소개시켜드린 속성 외에도 LinearLayout의 weight 속성과 같이 ConstraintLayout에도 비율에 맞게 뷰를 배치할 수 있는 속성이라던가 여러 유용한 속성들이 많이 있기 때문에, 앞으로도 ConstraintLayout에 대한 공부가 많이 필요하다고 느꼈던 것 같습니다.
지금까지 부족한 글 읽어주셔서
감사합니다😊
참고
Allow TextView to grow until a certain point in constraint layout
There is TextView1 and TextView2. TextView2 should float on the right side of TextView1. TextView1 should grow to the right as long as the total width of both text views do not make TextView2 overlap
stackoverflow.com
'Android' 카테고리의 다른 글
[안드로이드 / Kotlin] RecyclerView 최상단 최하단 스크롤감지 (0) | 2022.11.11 |
---|---|
[안드로이드 / Kotlin] Snackbar에 커스텀 폰트 적용하기 (0) | 2022.11.08 |
[안드로이드 / Kotlin] ViewPager2 setCurrentItem duration (0) | 2022.10.28 |
[안드로이드 / Kotlin] Moshi (2) | 2022.09.30 |
[안드로이드 / Kotlin] Clean Architecture 개념 (0) | 2022.09.18 |