개발을 하다 보면 동적으로 View들의 위치를 옮겨주거나 크기를 변경하는 등
Layout이나 View들을 코드에서도 바꿔야 할 경우가 생긴다.
코드에서 지정하기 위해 LayoutParam을 사용한 것을 포스팅한다.
LayoutParam은 부모 레이아웃 안에서 View(뷰)가 어떻게 배치될지를 정의하는 속성
구체적으로 레이아웃 XML파일에서 앞에 layout_""이 붙는 속성들을 말하며, LayoutParams 클래스의 필드값과 매핑된다.
따라서 코드 상에서 LayoutParams객체를 통해 뷰의 레이아웃 파라미터 속성을 다룰 수 있다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
위와 같은 xml파일에서 andorid:layout_width, andorid:layout_height 가 레이아웃 파라미터이다.
LayoutParams 클래스 구조
ViewGroup.LayoutParams
- ConstraintLayout.LayoutParams
- MotionLayout.LayoutParams
- AbsoluteLayout.LayoutParams
- ViewGroup.MarginLayoutParams
- GridLayout.LayoutParams
- FrameLayout.LayoutParams
- RelativeLayout.LayoutParams
- LinearLayout.LayoutParams
- TableLayout.LayoutParams
- CoordinatorLayout.LayoutParams
최상위의 ViewGroup.LayoutParams은 width, height 필드를 갖으며, 생성자는 아래와 같다.
LayoutParams(int width, int height)
여기서 정의한 width, height가 XML상의 layout_widht, layout_height와 매핑된다고 보면 된다.
따라서 하위의 LayoutParams들도 widht, height 필드를 갖으며, 각각의 레이아웃 스타일에 맞는 필드값을 추가로 갖는다고 한다.
이것을 이용해서 View나 View들의 부모 Layout을 통해 View의 width, height, margin, padding 그리고 사용한 Layout의 제약조건 등을 조작할 수 있다.
여러 LayoutParams 종류 사용
binding을 이용해 todayQuizScore라는 TextView가 있다고 할 때 각 TextView가 감싸고 있는 부모 Layout에 따라 여러 속성을 조작할 수 있다.
기본적인 width, height, margin, padding 등은 속성 파라미터가 똑같고 사용하는 제약 조건들을 사용
ConstraintLayout Programmatically
ConstraintSet을 지정해 제약조건 지정
binding.todayQuizScore.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT).apply {
//생성자에서 바로 width,height 줄수도 있음
//넓이, 높이
width = resources.getDimensionPixelSize(R.dimen.common_84dp)
height = resources.getDimensionPixelSize(R.dimen.common_48dp)
//margin - 구분 따로된 것
marginEnd = resources.getDimensionPixelSize(R.dimen.common_2dp)
setMargins(0,0,0,0) //margin left, top, right, bottom 한번에 적용
//padding
paddingTop = resources.getDimensionPixelSize(R.dimen.common_2dp)
setPadding(0,0,0,0)
//ConstraintSet 제약조건
bottomToBottom = ConstraintSet.PARENT_ID //부모 View
endToEnd = ConstraintSet.PARENT_ID
startToStart = R.id.result_banner //대상 View id
topToTop = R.id.result_banner
bottomToBottom = -1 //remove Constraint /제약조건 삭제
horizontalChainStyle = ConstraintSet.CHAIN_PACKED
horizontalChainStyle = ConstraintSet.CHAIN_SPREAD
verticalChainStyle = ConstraintSet.CHAIN_SPREAD_INSIDE
}
아래는 다른 방식의 set방법
ConstraintSet().apply {
clone(binding.layoutQuiz) //부모 ConstarintLayout의 ConstarintSet
setVerticalWeight(binding.itemLayout.id, 160f ) //조작할 자식뷰 id
setDimensionRatio(binding.itemLayout.id, "200:100")
setHorizontalBias(binding.itemLayout.id, 0.5F)
applyTo(binding.layoutQuiz) //부모 ConstarintLayout에 적용
}
RelativeLayout Programmatically
addRule()로 RelativeLayout에서 지정해 주는 제약조건을 지정할 수 있다.
binding.todayQuizScore.layoutParams = RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
width = if (score >= 100) resources.getDimensionPixelSize(R.dimen.common_84dp)
else resources.getDimensionPixelSize(R.dimen.common_57dp)
height = resources.getDimensionPixelSize(R.dimen.common_48dp)
marginEnd = resources.getDimensionPixelSize(R.dimen.common_2dp)
//ALIGN_PARENT_TOP, ALIGN_PARENT_BOTTOM, ALIGN_PARENT_START, ALIGN_PARENT_END
addRule(RelativeLayout.ALIGN_PARENT_TOP)
//ABOVE, BELOW, LEFT_OF, RIGHT_OF
addRule(RelativeLayout.ABOVE, R.id.result_banner) //대상 View id
}
LinearLayout Programmatically
LinearLayout에서 자주 사용하는 것은 weight와 gravity가 있겠다.
binding.todayQuizScore.layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENTT).apply {
weight = 1f
//TOP, BOTTOM, START, END, CENTER, CENTER_VERTICAL, CENTER_HORIZONTAL
gravity = Gravity.TOP
}
GridLayout Programmatically
GridLayout은 layout_columnWeight 속성정도를 사용할 것 같아 정리한다.
binding.quizItem1.layoutParams = GridLayout.LayoutParams(
GridLayout.spec(GridLayout.UNDEFINED, GridLayout.FILL, 1f),
GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f)
)
Programmatically LayoutParam
https://curryyou.tistory.com/373
https://stackoverflow.com/questions/12728255/in-android-how-do-i-set-margins-in-dp-programmatically
'Android > Reference' 카테고리의 다른 글
RecyclerView Item에 Animation 주기 (0) | 2022.04.18 |
---|---|
ItemDecoration / RecyclerView Item 간격 조정 (0) | 2022.04.10 |
OutLineTextView 글자 외곽선 (0) | 2022.04.03 |
Context (0) | 2022.03.28 |
ClipboardManager 클립보드에 복사 후 붙여넣기 (0) | 2022.03.16 |