티스토리 뷰

android

view ratio 강제 적용하기

길 킴 2023. 4. 18. 09:59
728x90

특정한 뷰의 가로 세로 비율을 특정 값으로 조정하고 싶은 경우가 있다. 어떠한 방법들이 있을까? 

가로 세로 비율을 1: 0.61 (세로 길이 = 가로길이 * 0.61) 로 지정한다는 가정하에 코드를 살펴보겠다. 

1. Programatically 하게 적용하기 

binding.ivCompany.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                binding.ivCompany.viewTreeObserver.removeOnGlobalLayoutListener(this)
                binding.ivCompany.layoutParams.height = (binding.ivCompany.measuredWidth * 0.61).toInt().apply {
                    itemHeight = this
                }
            }
        })

1번 방법은 단점이 명확해서 지양하는 편이다. 

단점

  • 불필요한 코드가 덕지덕지 길어진다. (가독성 좋지않아📄)
  • 요즘엔 Multi Window, 폴더블 폰 등 사용중에 화면 Resizing 이 되는 케이스가 상당이 많아졌다. 이럴때마다 height 값을 또 set 해줘야한다. 

 

2. PercentLayout 이용하기 

<android.support.percent.PercentRelativeLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ff0000"
        android:layout_centerInParent="true"
        app:layout_heightPercent="80%"
        app:layout_widthPercent="80%">
 
        <android.support.percent.PercentRelativeLayout
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="#ffff00"
            app:layout_heightPercent="40%"
            app:layout_marginLeftPercent="10%"
            app:layout_marginTopPercent="10%"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            app:layout_widthPercent="40%"/>

이 친구는 전체 뷰 기준으로 percent가 적용된다. height가 특정 dp로 고정되거나, 기기 사이즈 대비 비율을 산정할 때 유용하다. 

전체 기기 사이즈 또는 고정 길이 기준이 아닌, 특정 이미지뷰의 가로 세로 비율을 정하는 로직에서는 맞지 않았다. 

다른 방법을 찾기 시작했다. 😭

 

3. Constraintlayout 속성 활용하기 

3번의 방법을 가장 추천하는 편이다. 

ConstraintLayout 하위에 있을경우에만 사용이 가능한 단점이 있으나, 이제 ConstraintLayout을 메인으로 사용하니 큰 문제는 없다. 

layout_constraintDimensionRatio 의 경우 1 : 0.61 처럼 한눈에 비율이 들어오기 때문에 코드 가독성에서도 아주 우수하다. 
layout_aspectRatio 의 경우도 사용이 편하긴하나, app:layout_aspectRatio="178%" 처럼 생각보다 가독성에서 좋지는 않은 것 같다. 

3.1) layout_constraintDimensionRatio 옵션 활용 

app:layout_constraintDimensionRatio="H,1:0.61"
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/cl_wrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        android:paddingBottom="20dp">

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/card"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:cardCornerRadius="8dp"
            app:cardElevation="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintDimensionRatio="H,1:0.61"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <ImageView
                android:id="@+id/iv_company"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@{recruit.imageUrl}"
                tools:src="@tools:sample/avatars" />
        </com.google.android.material.card.MaterialCardView>

3.2) layout_aspectRatio 옵션 활용 

app:layout_aspectRatio="178%"
  <ImageView
        android:id="@+id/iv_company"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        app:layout_aspectRatio="178%"
        app:imageUrlWithRadius="@{recruit.imageUrl}"
        app:radius="@{8}"
        tools:src="@tools:sample/avatars" />

 

특정 뷰의 고정비율을 사용하고자 한다면 위의 방법중에 하나를 골라서 사용하면 된다.

더 좋은 방법이 발견된다면 계속 추가할 예정! ✌️

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함