Android

[안드로이드/데이터입출력] XML을 이용해 View 객체 생성

gangmini 2023. 4. 29. 00:25
반응형

Layout Inflater 

  • 앱 실행 도중 View를 만들어 추가할 경우 코드에 layout inflater로 xml을 View 객체로 만들어 사용
  • layoutInflater.inflate 메서드를 사용하면 XML을 통해 View 객체를 만듬
    • 두번째 인자로 null 을 넣어주는 방식 -> addView()를 통해 나중에 추가 / 추가되고자 하는 레이아웃을 넣어주는 방식 -> 처음부터 화면에 구성되어져 나옴, removeView() 불가능
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater) // 뷰바인딩 객체
    val view = binding.root //뷰바인딩을 통해 레이아웃과 뷰가 결합 -> .root 를 통해 View 객체만를 뽑아내는(?)
    setContentView(view)

    // View 객체 생성
    val sub_layout = layoutInflater.inflate(R.layout.custom_list,null)
    val sub_layout2 = layoutInflater.inflate(R.layout.activity_second,null)
    val sub_layout3 = layoutInflater.inflate(R.layout.activity_thrid, binding.container) //새로운 layout의 view들이 binding.container에 자동으로 추가 // removeView로 제거 불가능
    // 액티비티 화면 나타나자마자 화면 구성하는 용도임 (나중에 추가하는 방식에 적합 x)

    binding.button.setOnClickListener {
        binding.container.addView(sub_layout) //추가
        binding.container.addView(sub_layout2)

        // sub layout의 뷰에 접근하는 경우가 많다면 뷰바인딩을 하는게 더 편리할 수 있
        sub_layout.findViewById<Button>(R.id.button3).setOnClickListener {
            binding.textView.text = "sub의 버튼을 눌렀습니다"
            sub_layout.findViewById<TextView>(R.id.custom_text).text = "sub의 버튼을 눌렀습니다"
        }
    }

    binding.button2.setOnClickListener {
        binding.container.removeView(sub_layout) //제거
        binding.container.removeView(sub_layout2)
    }

}

 

val sub_layout3 = layoutInflater.inflate(R.layout.activity_thrid, binding.container

위와 같은 방식으로 뷰를 화면에 추가한 다음, addView()를 통해 뷰를 추가하려고 '뷰 추가' 버튼을 눌렀으나 동작하질 않으면서 앱이 죽는 문제가 발생함.

 

[error 내용]

 

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

[해결방법]

액티비티가 나올때 바로 추가된 뷰의 XML LinearLayout의 높이가 match_parent로 되어있으면서 처음 추가된 이후 container를 꽉 채우면서 더이상 다른 뷰 객체들이 추가될 수 없었던 것이다. 따라서 match_parent -> wrap_content 로 바꿔주어 문제를 해결할 수 있다.

반응형