본문 바로가기
깡샘 코틀린

06-2 뷰 클래스

by 농농씨 2023. 6. 15.

티스토리 단축키 확인 ctrl + '/' 키 

코드블록 단축키 alt+ctrl+','

 

뷰 클래스의 기본 구조

뷰 객체의 계층 구조

액티비티 화면을 구성할 때 사용하는 클래스는 모두 View의 하위 클래스이다. 그래서 화면구성과 관련한 클래스를 통칭하여 뷰 클래스라고 한다.

뷰 클래스의 하위에는 다양한 클래스가 있고 각 클래스의 역할은 다음과 같다.

  • View: 모든 뷰 클래스의 최상위 클래스. 액티비티는 이 클래스의 서브 클래스만 화면에 출력함
  • ViewGroup: View의 하위클래스지만 자체 UI는 없어서 화면에 출력해도 아무것도 나오지 않음. 다른 뷰 여러개를 묶어서 '제어'하는 목적. 그릇 역할. 컨테이너 기능 담당. 실제로는 ViewGroup의 서브클래스인 레이아웃클래스를 사용함.
  • TextView: 특정 UI를 출력할 목적으로 사용하는 클래스. 문자열을 출력하는 뷰이다.
  • ... 이외에도 다양한 클래스가 있다.

객체의 계층 구조에서 중요한 역할을 하는 것이 ViewGroup 클래스의 하위인 레이아웃클래스이다. 

레이아웃클래스만 있으면 아무것도 출력되지 않지만 화면 자체가 목적이 아닌 다른 뷰(TextView, ImageView 등) 객체 여러 개를 담아서 한꺼번에 제어할 목적으로 사용한다. 그릇역할!

따라서 레이아웃 클래스에 다른 뷰를 포함해 화면을 구성한다. 한꺼번에 출력하거나 정렬하는 등 편리하게 제어할 수 있게 한다.

 

레이아웃 중첩

뷰의 계층구조는 레이아웃 객체를 중첩해서 복잡하게 구성할 수 있다.

이처럼 객체를 계층 구조로 만들어 이용하는 패턴컴포지트 패턴(composite pattern) 또는 문서 객체 모델(document object model)이라고 한다.

 

레이아웃 XML의 뷰를 코드에서 사용하기

뷰의 구조에이어 어떻게 작성하는지 알아보자

화면구성을 레이아웃 XML파일에 작성하고 액티비티에서 setContentView() 함수로 XML 파일을 지정하면 화면을 출력한다.

예를들어 코드를 어케어케해서 "hello"를 출력하게 하면 XML태그로 입력한 TextView 객체가 생성되고 그 객체의 내용이 화면에 출력된다. 

그런데 때로는 이렇게 XML에 선언한 객체를 코드에서 사용해야 할 때가 있다. 이때 문제는 우리가 직접 생성한 객체가 아니므로 이름이 없어서 지칭할 수가 없다는 것이다. 결국 방법은 각 객체를 어떻게 부를 것인지 식별자를 부여하고 그 식별자로 객체를 얻어 와야 한다. 이때 사용하는 속성이 id이다.

id는 꼭 지정해야 하는 속성은 아니며 레이아웃 XML에 선언한 뷰를 구별할 필요가 없을 때는 생략해도 된다.

// id 속성 부여 예시
android:id="@+id/text1"

id 속성은 위와 같은 형태로 추가한다. 위 코드에서 text1이 id값이다. 이 값은 식별자로 이용할 것이므로 앱에서 유일해야 한다. 이처럼 XML에 id속성을 추가하면 자동으로 R.java 파일에 상수 변수로 추가된다.

id 속성값은 "@+id/text1"형태로 추가하는데 XML 속성값이 @로 시작하면 R.java 파일을 의미한다. 따라서 이 표현식은 R.java 파일에 text1이라는 상수변수를 추가하라는 의미이다. 

이제 코드에서 R.java 파일의 상수 변수로 객체를 얻을 수 있다. 이때 findViewById() 함수를 이용한다.

// 코드에서 XML에 입력한 객체 사용법
setContentView(R.layout.activity_main) // 액티비티 화면 출력(뷰 객체 생성)
// id값으로 뷰 객체 획득
val textView1: TextView = findViewById(R.id.text1)

setContentView()는 액티비티의 화면을 출력하는 함수이다. 이 함수를 호출하는 것만으로도  XML의 내용이 액티비티 화면에 출력된다. 화면에 뷰의 내용이 나왔다는 것은 뷰 객체가 생성되었다는 것을 의미한다. 이렇게 생성된 뷰 객체를 findViewById(R.id.text1)처럼 가져오면 된다.

findViewById() 함수로 얻은 뷰 객체의 타입을 제네릭으로 명시해도 된다.

(제너릭 복습 https://dreaminsweetpotato.tistory.com/15)

(뭐지... 제너릭 뭐지...이해안돼....)

// 제너릭으로 가져온 뷰 객체
// XML 화면 출력, 뷰 객체 생성 완료
setContentView(R.layout.activity_main)
// id값으로 뷰 객체 획득
val textView1 = findViewById<TextView>(R.id.text1)

 

뷰의 크기를 지정하는 방법

뷰를 레이아웃 XML에 등록하여 화면을 구성할 때 크기는 필수 정보이다.

이 크기를 설정하는 속성은 layout_width, layout_height 이다.

// 필수 속성인 크기가 사용된 것을 확인하라
<TextView
	android:id="@+id/text1"
    android:layout_width="wrap_content" // 크기 연관 속성
    android:layout_height="wrap_content" // 크기 연관 속성
    android:text="hello" />

크기를 나타내는 속성값에는 다음 3가지 중 하나를 선언한다.

  • 수치
  • match_parent
  • wrap_content

가로세로 크기를 100px처럼 크기로 수치로 지정할 수도 있다. 이때 단위는 생략할 수 없으며 px, dp 등의 단위를 사용한다.

또는 match_parent나 wrap_content처럼 특정한 단어로 지정할 수 있다.

match_parent➡️부모의 크기 전체를 뜻함

앞서 살펴보았듯 뷰 객체는 '계층 구조'로 이용하므로 어떤 뷰의 크기가 match_parent이면 자신보다 상위 계층의 크기를 뜻함.

wrap_content➡️자신의 콘텐츠를 화면에 출력할 수 있는 적절한 크기를 의미함

만약 문자열이 길어지거나 글꼴이 커지면 뷰 크기도 따라서 커짐

 

※ 보통 안드로이드 기기의 다양성때문에, 수치를 지정하기보다 wrap_content나 match_parent같은 상대적인 크기를 지정한다. 

 

 

뷰의 간격 설정

뷰의 간격은 margin과 padding속성으로 결정한다. 물론 기본값이 있으며 이를 바꿀 때 설정한다.

margin 속성 ➡️ 뷰와 뷰 사이의 간격

padding 속성 ➡️ 뷰의 콘텐츠와 테두리 사이의 간격

margin, padding 속성을 이용하면 간격이 네 방향 모두 같은 크기로 설정된다. 만약 특정한 한 방향의 간격만 설정하고 싶다면 paddingLeft, paddingRight, paddingTop, paddingBottom

layout_marginLeft, layout_marginRight, layout_marginTop, layout_marginBottom

속성을 이용한다.

 

 

뷰의 표시 여부 설정

visibility 속성은 뷰가 화면에 출력되어야 하는지를 설정한다. 값을 visible, invisible, gone으로 설정하며 기본값은 visible이다. 

visibility 속성을 설정한다는 것은 의도적으로 invisible, gone으로 값을 설정해 뷰가 화면에 보이지 않게 하려 한다는 뜻.

invisible과 gone은 둘 다 안보이지만 자리를 차지하는지 여부에 따라 다르다.

invisible은 안보이지만 자리를 차지하고, gone은 자리도 없다.

보이지 않는 속성을 처리하는 이유는 보이지 않다가 어느 순간 보이게 하기 위해.

// 코드에서 visibility 속성값 변경
visibleBtn.setonClickListener {
	targetView.visibility = View.VISIBLE
}
invisibleBtn.setOnClickListen {
	targetView.visibility = View.INVISIBLE
}

만약 XMl이 아닌 코드에서 뷰의 visibility 속성을 조정하려면 뷰의 visibility 속성값을 View.VISIBLE이나 View.INVISIBLE로 설정하면 된다.

 

'깡샘 코틀린' 카테고리의 다른 글

06-4 뷰 바인딩  (2) 2023.06.17
06-3 기본적인 뷰 살펴보기  (1) 2023.06.17
06-1 화면을 구성하는 방법  (2) 2023.06.15
05-2 널 안정성  (0) 2023.06.15
05-1 람다 함수와 고차 함수  (0) 2023.06.15