Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Android
- ViewModel
- activity
- recyclerview
- hilt
- kotlin
- HTTP
- notification
- CoordinatorLayout
- CustomView
- 알림
- 알고리즘
- 코틀린
- BOJ
- AppBarLayout
- DataBinding
- onMeasure
- onLayout
- CollapsingToolbarLayout
- 백준
- LiveData
- Algorithm
- Behavior
- room
- View
- Navigation
- sqlite
- 안드로이드
- Coroutine
- lifecycle
Archives
- Today
- Total
개발일지
Android in A..Z - View (CustomViewGroup) 본문
CustomeViewGroup
Android에서 기본으로 제공하는 ViewGroup(Layout) 대신 ViewGroup을 상속받아 UI를 구축할 수 있다.
OverlapLayout 전체코드
class OverlapLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : ViewGroup(context, attrs, defStyleAttr, defStyleRes) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var width = 0
var height = 0
measureChildren(widthMeasureSpec, heightMeasureSpec)
for (i in 0 until childCount) {
if (i == childCount - 1) {
width += get(i).measuredWidth
height += get(i).measuredHeight
} else {
width += get(i).measuredWidth / 2
height += get(i).measuredHeight / 2
}
}
val w = if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
MeasureSpec.getSize(widthMeasureSpec)
} else {
width
}
val h = if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
MeasureSpec.getSize(widthMeasureSpec)
} else {
height
}
setMeasuredDimension(w, h)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var left = 0
var top = 0
for (view in children) {
view.layout(left, top, left + view.measuredWidth, top + view.measuredHeight)
left += view.measuredWidth / 2
top += view.measuredHeight / 2
}
}
}
onMeasure
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var width = 0
var height = 0
measureChildren(widthMeasureSpec, heightMeasureSpec)
for (i in 0 until childCount) {
if (i == childCount - 1) {
width += get(i).measuredWidth
height += get(i).measuredHeight
} else {
width += get(i).measuredWidth / 2
height += get(i).measuredHeight / 2
}
}
val w = if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
MeasureSpec.getSize(widthMeasureSpec)
} else {
width
}
val h = if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
MeasureSpec.getSize(widthMeasureSpec)
} else {
height
}
setMeasuredDimension(w, h)
}
ViewGroup은 ChildView의 크기를 계산해서 자신의 크기를 측정해야한다. ChildView가 있는 View가 그려지는 과정은 전위순회 방식이기 때문에 measurChildren을 통해 ChildView의 크기를 측정(각 View마다 measure로 개별적인 MeasureSpec으로 측정할 수도 있다.)하고 자신의 크기를 측정한다.
onLayout
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var left = 0
var top = 0
for (view in children) {
view.layout(left, top, left + view.measuredWidth, top + view.measuredHeight)
left += view.measuredWidth / 2
top += view.measuredHeight / 2
}
}
onLayout은 View의 위치를 정하는 함수로 ChildView의 위치를 계산하여 layout 함수를 호출해준다.
* 매개변수로 넘어오는 l, t, r, b는 절대위치 값이다.
XML
<com.taetae98.customview.view.OverlapLayout
android:id="@+id/overlap"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:adjustViewBounds="true"
android:src="@drawable/dog"
android:layout_width="100dp"
android:layout_height="wrap_content" />
<ImageView
android:adjustViewBounds="true"
android:src="@drawable/cat"
android:layout_width="100dp"
android:layout_height="wrap_content" />
<ImageView
android:src="@drawable/bird"
android:adjustViewBounds="true"
android:layout_width="100dp"
android:layout_height="wrap_content" />
</com.taetae98.customview.view.OverlapLayout>
Git (예제코드)
github.com/KangTaeJong98/Example/tree/main/Android/CustomView
'Android (안드로이드) > View' 카테고리의 다른 글
Android in A..Z - View (Draw Step) (0) | 2021.10.04 |
---|---|
Android in A..Z - View (CustomView-Extend) (0) | 2021.04.30 |
Android in A..Z - View (MeasureSpec) (0) | 2021.04.29 |
Android in A..Z - View (CustomView) (0) | 2021.04.29 |
Android in A..Z - View (AttributeSet) (0) | 2021.04.29 |
Comments