Layout 동적 생성.
xml 레이아웃을 코틀린 코드로 생성해야되는 상황이 발생했다.
adapter class에서 getItem으로 데이터를 외부로부터 받아오면
해당 데이터를 이용하여 3가지 Layout을 동적으로 추가.
- TextView,
- RadioButton,
- CheckBox
레이아웃을 추가하는 루틴? 과정은 비슷하고, 각 뷰 마다 디테일하게 설정해줘야 하는 점이 조금씩 다르고, 상위 뷰에 딸린 attr을 설정해주기 위해서는 LayoutParams을 이용해야 한다.
layout.xml
list_item_menu_option_radio_btn.xml
//list_item_menu_option_radio_btn.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline">
</RadioGroup>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintGuide_percent="0.5"
android:orientation="vertical" />
<LinearLayout
android:id="@+id/layout_textbox"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="vertical">
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
이와 같이 라디오버튼이 들어갈 <RadioGroup> 과 TextView가 들어갈 <LinearLayout> 을 미리 만들어놓고, 동적으로
해당 viewGroup에 View들을 생성하여 넣어줄 계획.
만약 view를 의도한대로 설정하여 viewGroup에 추가한다면 이와 같은 layout이 만들어질 것이다.
Kotlin - 기본 설정
우선 view를 추가하고 싶다면
//context는 뷰가 나타날 UI의 context
val textview = TextView(context)
val radioBtn = RadioButton(context)
val checkBox = CheckBox(context)
다음과 같이 해당 View를 생성해야 한다. context를 인자로 넣어줘야 하는데 이는 UI의 context를 갖고 오도록하자.
다음에는 view의 id, text 등 기본적으로 view의 정보와 보여줄 데이터를 넣도록 하자.
textView.id = 외부데이터.id
textView.text = 외부데이터.text
textView.gravity = Gravity.CENTER or Gravity.END
radioBtn.id = 외부데이터.id
radioBtn.text = 외부데이터.text
checkBox.id = 외부데이터.id
checkBox.text = 외부데이터.text
다음과 같이 외부데이터를 이용하여 각 view의 id와 text를 설정해줄 수 있다.
이후에는 코드에서 생성한 view객체들이 실제로 추가될 레이아웃에 넣어보도록 하자.
layout.xml에서 만든 @+id/radioGroup 이나 @+id/layout_textview 의 바인딩을 이용.
//binding : ListItemMenuOptionRadioBtnBinding
binding.layoutTextview.addView(textView)
binding.radioGroup.addView(radioBtn)
addView() 메서드를 이용하여 각 view를 추가한다.
view의 Gravity를 2개 이상 설정해주기 위해서는 or을 이용한다.
textView.gravity = Gravity.CENTER or Gravity.END
Kotlin - 심화 설정 LayoutParams
기본적으로 view를 추가했지만, 실제로 view를 추가할 때는 view가 보여질 위치, view의 색상,크기 등 개발자가 설정해야할 attr 들이 많다.
이는 각 view의 객체로만 설정할 수 있는 attr이 있는가하면 view가 속한 viewGroup의 attr을 통해 view의 세부설정을 바꿀 수도 있을 것이다.
예를 들어
LinearLayout 내에 있는 View는 layout_weight라는 세부 속성을 설정할 수 있지만 ,
ConstraintLayout에 있는 View는 layout_weight라는 세부속성은 존재하지 않고, top_topOf 와 같은 또다른 세부속성이 생긴다.
따라서 상위 뷰그룹의 LayoutParams를 생성하고 이를 통해 하위 View의 세부속성을 설정해줄 수 있다.
val params = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
params.weight = 5F
textView.layoutParams = params
binding.layoutTextview.addView(textView)
이처럼 변수 params에 LinearLayout (<- TextView가 속한 viewGroup의 레이아웃) 의 LayoutParams를 만들어준 뒤
인자로는 기본적인 width와 height을 설정하여 넣어준다.
params.weight를 설정해주고
textView의 layoutParams 을 해당 params 값으로 설정해준 뒤 addView.