안드로이드에서 XML은 어디에 사용할까?
- 애니메이션
- 이미지
- UI 레이아웃
- 메뉴
- 앱 탐색 그래프
- 리소스 (문자열, 크기, 색상 등)
…
다양한 곳에 사용하고 있다!
어떻게 사용될까?
개발할때,조금더신경쓰면좋을내용을다뤄봅시다.
Slide 5
Slide 5 text
가끔버튼이잘안눌러지는부분이있다.
1
Slide 6
Slide 6 text
버튼이 잘 안 눌러지는 이유
주로 이미지 버튼에서 발생하는데,
View 영역이 손가락으로 누를 수 있을만큼
적절하게 확보되지 않는 것이 원인이다.
Slide 7
Slide 7 text
Link: https://material.io/design/usability/accessibility.html#layout-and-typography
Material Design에서는 최소 48 x 48 dp 만큼의
터치영역을 확보하는 것을 권장한다.
Slide 8
Slide 8 text
버튼이 잘 안 눌러지는 이유
Margin은 View 터치 영역으로 간주되지 않는다.
디자인 가이드를 맹목적으로 따르지 말고
사용성을 고려하여 터치영역을 적절히 확보하는 것이 좋다.
Slide 9
Slide 9 text
목표
놓치기쉬운 안드로이드UI디테일살펴보기
Slide 10
Slide 10 text
목표
놓치기쉬운 안드로이드UI관련 XML디테일살펴보기
Slide 11
Slide 11 text
클릭 효과가 이미지 아래에 그려져서
보이지 않는 경우가 있다.
2
Slide 12
Slide 12 text
버튼이 안 눌러지는 것처럼 보이는 이유
이럴 때는 foreground와 같은 속성을
사용하여 해결할 수 있다.
Slide 13
Slide 13 text
버튼이 안 눌러지는 것처럼 보이는 이유
안드로이드 앱은 OS 버전에 따라 API가 지원되지 않을 수 있다.
이 때는 적절한 대안을 만들면 된다.
Slide 14
Slide 14 text
버튼이 안 눌러지는 것처럼 보이는 이유
그런데 FrameLayout에서는 API 21에서도 foreground 속성이 잘 동작한다.
도대체 왜?
Slide 15
Slide 15 text
Link: http://androidxref.com/5.0.0_r2/.../android/widget/FrameLayout.java
L 까지는 FrameLayout의 속성이었다.
Slide 16
Slide 16 text
Link: http://androidxref.com/6.0.0_r1/.../android/view/View.java
M 부터는 View의 속성으로 변경되었다.
Slide 17
Slide 17 text
버튼이 안 눌러지는 것처럼 보이는 이유
사용하는 View(=FrameLayout)에 있는 속성만 아니라
상속하는 상위 View 속성도 사용할 수 있다는 것을 알 수 있다.
Slide 18
Slide 18 text
레이아웃 XML이 화면에 어떻게 그려지게 되는지
과정이 궁금하다면?
3
Slide 19
Slide 19 text
LayoutInflater
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
@Override
public void setContentView(int resId) {
...
LayoutInflater.from(mContext).inflate(resId, ...);
...
}
Slide 20
Slide 20 text
Link: http://androidxref.com/9.0.0_r3/.../android/view/LayoutInflater.java
단순히 레이아웃 XML을 파싱해서
View 구현체로 변환해주는 방식이다.
Slide 21
Slide 21 text
LayoutInflater
따라서 XML 코드는
실제 구현체로 변환해주는 단계가 반드시 필요하다.
Slide 22
Slide 22 text
LayoutInflater
View는 선언된 순서대로 그려진다.
레이아웃이 겹쳐지는 경우에는 고민이 필요하다.
(ex. RecyclerView + Button 등)
Slide 23
Slide 23 text
LayoutInflater
Z축을 변경하는 방법을 사용할 수도 있다.
단, BG가 있으면 그림자 효과가 나타나니 주의할 것.
Slide 24
Slide 24 text
4
android:tint 속성을 이용하여,
상태에 따라 아이콘 색상을 다르게 보여줄 수 있다.
Slide 25
Slide 25 text
AppCompat
하지만 API 21 미만에서는
런타임에 오류가 발생한다.
위 속성에서 발생한 문제다.
Slide 26
Slide 26 text
Link: http://androidxref.com/5.0.0_r2/.../android/widget/ImageView.java
L 부터는 ColorStateList를 허용한다.
Slide 27
Slide 27 text
Link: http://androidxref.com/4.4_r1/.../android/widget/ImageView.java
KK 까지는 Color 만 허용한다.
Slide 28
Slide 28 text
AppCompat
그렇다면 어떻게 해결할 수 있을까?
Slide 29
Slide 29 text
AppCompat
플랫폼 속성 대신 커스텀 속성으로 변경하면
API 21 미만에서도 ColorStateList가 동작한다.
무슨 차이가 있는 걸까?
Slide 30
Slide 30 text
android:tint 는 ImageView의 속성이고,
app:tint 는 AppCompatImageView의 속성이다.
Slide 31
Slide 31 text
Link: https://github.com/androidx/.../androidx/appcompat/widget/AppCompatImageHelper.java
AppCompatImageView는 ColorStateList를 허용한다.
따라서 API level에 관계없이 잘 동작한다.
Slide 32
Slide 32 text
AppCompat
잠깐! ImageView가 어떻게 AppCompatImageView가 된걸까요?
class MainActivity : AppCompatActivity()
비밀(?)은 상속에 숨어 있습니다.
LayoutInflater를 통해
레이아웃 XML을 View 구현체로 변환하려고 할 때,
우선적으로 Factory를 이용한다.
Slide 35
Slide 35 text
Link: http://androidxref.com/.../android/view/LayoutInflater.java
(이 부분은 MDC에서 사용됩니다.)
AppCompatViewInflater 내부에서
"ImageView" 태그는 AppCompatImageView로 생성해준다.
Style과 Theme
...
아무것도설정하지않은버튼의기본색상은뭘까?
즉, Theme는 자신을 포함하여 하위 View에도 영향을 준다.
Slide 44
Slide 44 text
현재 Theme의 buttonStyle 속성에서
배경 이미지를 참조한다.
Slide 45
Slide 45 text
Theme에서 기본 Style을 정의해두고 있고,
Style은 단일 View에 적용된다는 것을 알 수 있다.
Slide 46
Slide 46 text
Style과 Theme
상황에 따라 화면 단위로 Theme를 적절히 설정해주고,
세세하게 변경이 필요하면 해당 View에 Style을 설정하는 것을 추천한다.
Slide 47
Slide 47 text
6
...
혹시 배경이 흰색이 아니라서
root에 background를 설정한 적이 있다면?
Slide 48
Slide 48 text
WindowBackground
이 경우, 개발자 옵션으로 overdraw를 확인해보면
화면의 모든 영역이 불필요하게 한번씩 더 그려진다.
background 속성을 사용하지 않고,
기본 배경색을 변경할 수는 없을까?
Slide 49
Slide 49 text
WindowBackground
<item name="android:windowBackground">#ffffff</item>
...
windowBackground 속성을 이용하면 이 부분을 개선할 수 있다.
어디에 그려지는지는 직접 찾아보면 재미있겠죠?
Slide 50
Slide 50 text
7
drawable 많이 쓰시나요?
Slide 51
Slide 51 text
생각보다 강력한 Drawable
shape drawable에 Ripple 효과를 쉽게 추가할 수 있다.
Slide 52
Slide 52 text
생각보다 강력한 Drawable
Ripple 효과의 영역을 다르게 설정할 수도 있다. (= mask)
Slide 53
Slide 53 text
생각보다 강력한 Drawable
조금 복잡한 조건의 배터리 UI를 만들어보자!
A. 0 ~ 100% 단계가 1% 단위로 보인다.
B. 1 ~ 20% 단계에서는 빨간색으로 보인다.
C. 0 ~ 1% 단계에서는 경고 아이콘(❗)이 보인다.
D. 충전중에는 0 ~ 20% 단계에서도 검정색으로 보이고,
충전 아이콘(⚡)이 함께 보인다.
Java 또는 Kotlin 코드 없이도
이미지 5장만으로 구현할 수 있다면?
empty low full alert charge
Slide 54
Slide 54 text
생각보다 강력한 Drawable
⚡
selector, layer-list, level-list, clip 등을 혼합하면 가능하다.
먼저 충전중 상태부터 구현해보자.
임시로 Activated 상태를 충전중이라 가정했다.
이미지를 겹쳐 보여줘야 할 때 사용한다.
ProgressBar 처럼 이미지를 단계 별로 자를 때 사용한다.
Slide 55
Slide 55 text
생각보다 강력한 Drawable
❗
다음으로 기본 상태를 살펴보자.
level-list를 사용하여 각 level에 맞는 이미지 조합을 보여주자.
참고로 level은 0 ~ 10000 단계를 가진다.
Slide 56
Slide 56 text
생각보다 강력한 Drawable
val level: Int = ... // 0 ~ 100
val batteryView: ImageView = ...
batteryView.setImageLevel(level * 100)
batteryView.isActivated = isCharging
setActivated, setImageLevel API를 호출하면 구현 완료!
Drawable 구현체가 궁금하다면?
생각보다 강력한 Drawable
이외에도 다양한 Drawable 구현체가 있으므로,
직접 살펴보는 것을 추천한다!
Slide 60
Slide 60 text
8
#F2F2F2
#000000
res/values/colors.xml 다크모드를 지원하는 방법은?
Slide 61
Slide 61 text
Resource Qualifier
색상 외에 이미지 등 다른 리소스도
-night qualifier를 사용할 수 있다.
#202020
#FFFFFF
res/values-night/colors.xml
res/drawable/ic_drink.xml
res/drawable-night/ic_drink.xml
Slide 62
Slide 62 text
자세한 내용은 공식 문서를 참고하자.
Slide 63
Slide 63 text
Resource Qualifier
이외에도 다양한 Qualifier를 이용하여,
안드로이드의 파편화된 기기 생태계에 적응할 수 있다.
res/layout-land/activity_main.xml
res/values-v23/styles.xml
res/values-ko/string.xml
res/values-sw600dp/dimens.xml
Slide 64
Slide 64 text
이런 목록형 UI를 구현할 때의 과정을 생각해본다면
레이아웃 변경사항을 확인하려고 매번 빌드하지는 않았나?
9
Slide 65
Slide 65 text
tools 이용하기
레이아웃 XML을 작성하면 왼쪽 화면처럼 보인다.
빌드하기 전에 미리 볼 수 있는 방법이 있다면?
Slide 66
Slide 66 text
tools 이용하기
tools를 이용하여, 목록의 개수/방향 등을 설정할 수 있다.
Slide 67
Slide 67 text
tools 이용하기
미리 정의된 tools 샘플 데이터를 이용하면 좀 더 실제처럼 보인다.
Slide 68
Slide 68 text
tools 이용하기
{project}/{module}/sampledata/labels
샘플 데이터를 직접 정의할 수도 있다.
tools를 이용하여 빌드 횟수를 줄이고, 생산성을 높여보자.
I am debugging.
My foldable phone.
NAVER TECHCON 2020 ⷎ
Slide 69
Slide 69 text
정리
margin, padding
tools
Attribute LayoutInflater AppCompat, MDC
WindowBackground
Drawable
Qualifier
XML
오늘은 안드로이드를 구성하는 XML 코드에 대해서 살펴봤습니다.
어떤가요. 안드로이드 앱 개발 재미있어 보이지 않나요?
Style, Theme