발견록_08

김재현·2023년 8월 28일
0

안드로이드

목록 보기
11/12

1. Glide를 사용하는데 원본 이미지 사이즈랑 다르게 나올때

<ImageView
    android:id="@+id/ivCoachMark1"            
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:src="@drawable/chatbox_coach_marks_01"
    android:adjustViewBounds="true"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>

이렇게 ImageView를 통해 src에 내가 원하는 사진(여기서는 chatbox_coach_marks_01)을 넣고싶다고 하자.
이때 layout_width와 layout_height가 둘다 wrap_content로 되어있다. 인터넷을 검색해보면 이미지보다 height가 더 크게 잡힐 수 있으니 android:adjustviewBounds="true"를 설정해주라고 할 것이다.

그런데 여기서는 layout_width도 wrap_content이다!

그래서 원본의 이미지 사이즈가 200x120이라고 하더라도 glide가 자기 알아서 이미지를 크게 만들거나 할 수가 있는것 같다.

그럼 이때는 어떻게 해야하나?

import com.bumptech.glide.request.target.Target

fun ImageView.setOriginImage(drawableRes: Int?, @DrawableRes error: Int? = null) {
    Glide.with(context)
        .load(drawableRes)
        .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
        .error(error)
        .into(this)
}

기본 Glide사용법에서 .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)을 사용하는 것이다! 그럼 원본 이미지의 사이즈를 그대로 사용할 수 있다.

.override() 옵션은 가로길이, 세로길이를 내가 원하는 사이즈로 조정해줄 수 있다. 하지만 원본 이미지의 비율을 우선시 하기 때문에 정확히 그 사이즈가 안될 수 있다는 것을 생각해야한다.


2. 레이아웃에 그림자 넣기

constraintlayout과 같이 레이아웃에 그림자를 넣는 방법은 크게 세가지가 있는 것 같다.

  1. CardView로 만들어서 CardView의 자체적인 cardElevation을 사용해서 그림자를 넣는 방법
  2. Constraintlayout등의 일반적인 뷰에 elevation속성이나 translationZ속성을 넣어주는 방법
  3. drawable에 그림자 처럼 보이는 background를 만들어서 커스텀 그림자를 넣어주는 방식

이 세가지를 모두 활용해본 결과 어떤 문제점이 있었는지를 이야기 해보고자 한다.

  • 첫번째, 그림자를 넣어줬을때 만약 bottom쪽에 마진이나 padding으로 공간을 넣어주지 않는다면 밑의 그림자는 잘려서 보이지 않는다는 것이다. - 이 공간이라는 건 빈 View를 밑에 깔아주는 것으로도 해결된다.

  • 두번째, drawable을 통해 layer-list를 쌓아 그림자를 커스텀해서 만들어준다면 기존의 width,height영역보다 내가 설정하고 싶었던 영역이 작게 나온다는 것이다. (참고 사이트)

  • 세번째, cardElevation, elevation, translationZ을 넣어준다면 화면이 위로 올라감에 따라서 그림자가 옅어진다.

  • 네번째, android:outlineProvider="none"을 사용하면 cardElevation, elevation, translationZ를 통한 그림자가 보이지 않는다.

  • 다섯번째, elevation과 같이 축을 올리는것을 사용하면 레이아웃의 쌓임 순서를 충분히 고려해야한다.

  • 여섯번째, elevation 속성은 해당 뷰에 background 속성이 정의되어 있는 경우에만 작동한다

  • 일곱번째, 부모뷰의 padding이 있고, 자식뷰의 그림자가 놓을 공간이 없을 경우. clilpTopadding="false"속성을 사용하면 부모 컴포넌트의 padding공간을 그림자를 표시하는데 사용할 수 있다.


3. RTL언어 속성 고려하기

우리가 쓰는 언어는 평소에 왼쪽(Left) 에서(To) 오른쪽(Right)으로 쓰는 LTR 언어이다.
그런데 히브리어나 아랍어 같은 경우에는 오른쪽에서 왼쪽으로 쓰는 RTL언어이다. 이 경우 핸드폰에서 언어설정을 바꾸면 UI가 좌우가 바뀌는 것을 볼 수 있을 것이다.

그럼 내가 만든 앱은 어떻게 해야할까?
1. 그냥 LTR로 사용하게 사용자에게 강제한다.
2. RTL 버전을 만들어준다.

더 경우의 수가 있을 수 있겠지만 일단 2가지 경우를 설명해보고자 한다.

1. 그냥 LTR로 사용자에게 보여주기

이 경우는 그냥 신경쓰지 않고 코드를 하나도 안바꾼다면 그냥 LTR로 보일것이다. 아마?

2. RTL 버전을 만들어준다.

이 글의 핵심인 RTL 버전을 만드는 방법이다.

  • 첫번째로는 AndroidMenifest.xml에 설정을 추가해준다.
<application
    android:supportsRtl="true"
>

이걸 추가하게 되면 알아서 좌우가 바뀐것을 확인할 수 있을 것이다.
이때, 주의해야할 점이 있다.
만약 xml에 right나, left같은 속성을 넣었다면 start나 end로 바꿔주어야한다. 왜냐하면 좌우가 바뀌는것은 start나 end를 반대방향으로 알아서 설정해주는 것이기 때문이다. right나 left는 인식하지 못한다!
ex)

<View
    android:id="@+id/handleBar"
    android:layout_width="120dp"
    android:layout_height="4dp"
    android:layout_marginLeft="18dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

이런 식으로 적었다면 marginLeftmarginEnd로 바꿔주어야 한다는 소리이다.

  • 두번째로는 이미지의 좌우반전을 해주어야 한다는 점이다.

만약 화살표같은 이미지를 넣었다면 이미지의 위치는 위 방법을 통해서 바뀌었을지는 몰라도 이미지의 좌우반전은 되어있지 않을 것이다. 이를 바꿔주어야한다.

내가 생각한 가장 간단한 방법은 지금 로컬언어가 무엇인지 확인해서 좌우가 바뀐 사진으로 넣어주는 것이다.

val defaultLocale: Locale = Locale.getDefault()
val languageCode = defaultLocale.language.substring(0,2)

로 설정해서 languageCode를 확인하는 것이다. 히브리어는(iw), 아랍어는(ar)로 설정되기 때문에 그것을 검사하면 된다!

코드단에서 ImageView에 이미지를 넣는 방법은 여러가지 있으니 설명하지는 않겠다.

  • 세번째로는 Constraintlayout속성의 start와 end를 둘다 주었을때 문제다.

모든 경우에서 확인해보지는 못했지만, 필요없이 start와 end가 묶여있어서 체인이 걸려있을때 문제가 생기는 적이 있었다.

첫번째에서 말했다시피, 안드로이드는 좌우가 바뀌면 알아서 매칭시켜준다. 그런데 이때 문제가 생길 가능성이 있다는 것이다.

<View
    ...
    app:layout_constraintEnd_toStartOf="@id/view1"
    app:layout_constraintStart_toEndOf="@id/view2"
    app:layout_constraintTop_toTopOf="parent"/> 

그래서 뷰를 수정하거나 건드렸을때 체인이 걸리는 상황이라면 꼭 아랍어도 확인해서 제대로 뷰가 그려지는지 확인해보아야 한다. top, bottom은 상관없는것 같다.

이 문제는 커스텀으로 레이아웃을 그렸을때 문제가 생길 수 있다. RelativeLayout과 같은 걸 커스텀해서 글씨가 뷰를 지나치고 글을 쓸때와 같이 말이다.

  • 네번째로는 RTL 언어 속성이지만 LTR처럼 사용하고 싶을때나 뷰를 건드리지 말았으면 할때 사용하는 방법이다.

xml에 속성을 추가한다.

android:layoutDirection=""
android:textDirection=""
android:textAlignment=""

주로 이 세가지 속성을 사용해서 나는 문제를 해결하였다.

첫번째 layoutDirection은 이 뷰가 어떤식으로 방향을 할것인지 지정할 수 있다. ltr, rtl, locale이 있는데 ltr로 한다면 언어가 rtl로 바뀌어도 좌우가 바뀌지 않게된다.

두번째 textDirection은 주로 textView에서 사용했다.

세번째 textAlignment는 라고한다.

적절하게 사용하며 된다.!

난 주로 layoutDirection은 ltr와 locale을 사용하였고
textDirection에는 locale과 ltr, firstStrong을,
textAlignment는 viewStart를 사용하였다.


profile
배운거 정리하기

0개의 댓글