반응형
constraintlayout을 코틀린에서 런타임에 동적으로 제어해보자.
이때 binding은 뷰 바인딩 인스턴스이다.
- 전체코드
val constraintLayout = binding.root
val constraintSet = ConstraintSet()
constraintSet.clone(constraintLayout)
constraintSet.connect(binding.eyes.id, ConstraintSet.TOP, binding.face.id, ConstraintSet.TOP, 200)
constraintSet.connect(binding.eyes.id, ConstraintSet.START, binding.face.id, ConstraintSet.START, 10)
constraintSet.applyTo(constraintLayout)
eyes를 face의 TOP으로부터 200만큼, face의 START로부터 10만큼 떨어지게 했다.
다만 코드상에서는 XML과 달리 단위가 무조건 픽셀이다. 따라서 dp로 바꿔줄 필요가 있다. 아래는 dp를 픽셀 단위로 바꿔주는 함수이다.
fun convertDpToPixel(dp: Float, context: Context): Int {
return (dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)).toInt()
}
쓰일 일이 많을 것 같아 이를 좀 더 일반화해서 함수로 만들어봤다.
private fun constraintWidget(constraintLayout: ConstraintLayout, target: Int, standard: Int, startMargin: Float, topMargin: Float) {
val constraintSet = ConstraintSet()
constraintSet.clone(constraintLayout)
constraintSet.connect(target, ConstraintSet.START, standard, ConstraintSet.START, convertDpToPixel(startMargin, this))
constraintSet.connect(target, ConstraintSet.TOP, standard, ConstraintSet.TOP, convertDpToPixel(topMargin, this))
constraintSet.applyTo(constraintLayout)
}
private fun convertDpToPixel(dp: Float, context: Context): Int {
return (dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)).toInt()
}
- 사용
constraintWidget(binding.root, binding.eyes.id, binding.face.id, 36f, 56f)
root 레이아웃에서 eyes 위젯을 face를 기준으로 start에서 36dp, top에서 56dp 마진을 갖게 제약한다.
반응형