TIL 18: 자잘한 안드로이드 UI 팁들 2

TL;DR

  1. 코드로 inflate 할 때, root 매개변수로 전달한 인자에 따른 주의사항
  2. 코드로 inflate 할 때, margin이 적용되지 않는 경우
  3. ScrollView 자식으로 스크롤 뷰 형태의 뷰가 있을 때, 이중 스크롤을 방지하고 싶은 경우
  4. 클릭을 빠르게 두 번 했을 때, 이벤트가 두 번 발생하는 것을 방지하고 싶은 경우
  5. 코드로 높이, 너비 등과 같은 값을 설정하는 경우
  6. 뷰의 변환을 지속적으로 감지하고 싶은 경우
  7. ConstraintLayout 사용 시, 고정 높이가 적용되지 않는 경우
  8. ellipsizemiddle로 적용하는 경우 주의사항

자잘한 안드로이드 UI 팁들 2

유지보수를 하며 추가적으로 간단하게 정리했던 팁들이다.
앞서 작성했던 팁들은 바로 이전 글에서 확인할 수 있다.

1. 코드로 inflate 할 때, root 매개변수로 전달한 인자에 따른 동작 구분

root 매개변수에 부모 뷰를 전달하면, 부모 뷰에 addView() 메소드를 호출해 자식으로 추가되는 효과가 난다. 반대로, null을 전달하면 추가가 되지 않으므로 직접 추가를 해줘야 한다.

때에 따라 부모 뷰를 전달할 필요가 없기도 한다.
그런데 두 경우에 반환한 뷰가 서로 달라 주의가 필요하다.

  1. 부모 뷰를 전달한 경우: 부모 뷰가 반환된다.
  2. null을 전달한 경우: inflate 된 뷰가 반환된다.

2. 코드로 inflate 할 때, margin이 적용되지 않는 경우

분명히 XML 레이아웃에서 margin을 적용했는데, inflate 한 경우 실제로 적용되지 않는 것을 확인할 수 있다. 이 또한 root 매개변수에 부모 뷰를 전달했는지 안했는지에 따라 달라진다.

  1. 부모 뷰를 전달한 경우: margin이 정상적으로 적용된다.
  2. null을 전달한 경우: margin이 적용되지 않아 코드로 직접 적용해야 한다.

inflate 할 때 부모가 주어지면 margin을 판단할 수 있으나, 없다면 판단할 수 없어 발생하는 문제인 것 같다.

3. ScrollView 자식으로 스크롤 뷰 형태의 뷰가 있을 때, 이중 스크롤을 방지하고 싶은 경우

스크롤 뷰 형태의 뷰라 하면, RecyclerView, ScrollView, ListView 등 스크롤이 생길 수 있는 뷰를 말한다. 해당 뷰를 이용해서 데이터를 표현했지만, 높이를 고정시키고 싶을 때가 있을 것이다. 그런데 부모로 ScrollView를 그냥 사용하면, 고정 높이가 적용되지 않을 수가 있다.

부모에 해당하는 ScrollView 대신 NestedScrollView를 사용한다.
자식으로 스크롤 뷰 형태의 뷰를 가지면, 그냥 NestedScrollView를 사용하는 것이 속 편할 것 같다.
아니면 항상 ScrollView 대신 NestedScrollView를 사용하는 것도…

4. 클릭을 빠르게 두 번 했을 때, 이벤트가 두 번 발생하는 것을 방지하고 싶은 경우

클릭 이벤트에서 마지막으로 클릭한 시간을 기록했다가 현재 시간과 비교해 간격을 줄 수 있다.

아래와 같은 코드를 클릭 이벤트에 넣어 구현이 가능하다.

if (SystemClock.elapsedRealtime() - mLastClickTime < 1000){
    return;
}
mLastClickTime = SystemClock.elapsedRealtime();

하지만, 이것도 정말 빠르게 두 번 누르면 같은 현상이 발생한다…
추가적으로 다른 조치가 필요할 것 같다.

5. 코드로 높이, 너비 등과 같은 값을 설정하는 경우

코드로 해당 값들을 설정하는 메소드는 대부분 px 값을 수치로 전달 받는다.
만약, 디자인을 위해 dp 값 설정이 필요하다면, 반드시 변환해서 전달하도록 한다.

일반적으로 dpToPx()와 같은 유틸 메소드를 만들어 사용하곤 한다.

6. 뷰의 변환을 지속적으로 감지하고 싶은 경우

뷰의 ViewTreeObserver를 얻어 OnGlobalLayoutListener를 설정하면 지속적 감지가 가능하다. 하지만, 매우 자주 호출되므로 주의가 필요하다.

일회성 동작이라면, GlobalLayout 이벤트에서 해당 리스너를 지우도록 한다.

7. ConstraintLayout 사용 시, 고정 높이가 적용되지 않는 경우

layout_constrainedHeighttrue로 설정한다.

8. ellipsizemiddle로 적용하는 경우 주의사항

줄 수를 2줄 이상으로 허용하는 경우, ellipsizemiddle이면 경우에 따라 크래시가 발생할 수 있다. 따라서 2줄 이상인 경우에는 middle 값을 사용하지 않고, end와 같은 다른 값을 사용해야 한다.

1줄인 경우에는 middle 값을 사용하는 것에 문제가 없다.

TIL 19: Simple-Jekyll-Search 오픈 소스 기여 TIL 17: 자잘한 안드로이드 UI 팁들