목차
뷰 클래스의 기본 구조
안드로이드에서 화면을 만들어 표시하는 컴포넌트는 액티비티 이며,
액티비티가 실행되면서 뷰 클래스를 이용해 화면을 구성
뷰 객체의 계층 구조
액티비티 화면을 구성할 때 사용하는 클래스는 모두 View의 하위 클래스임
➡ 화면 구성과 관련한 클래스를 통칭하여 뷰 클래스라고 함
[뷰 클래스의 구조]
- View
- 모든 뷰 클래스의 최상위 클래스
- 액티비티는 View의 서브 클래스만 화면에 출력함
- ViewGroup
- View의 하위 클래스지만 자체 UI는 없어서 화면에 출력해도 아무것도 나오지 않음
- 다른 뷰 여러 개를 묶어서 제어할 목적으로 사용
- 일반적으로 컨테이너 기능을 담당한다고 이야기함
- 실제로는 ViewGroup의 서브 클래스인 레이아웃 클래스를 사용
- TextView
- 특정 UI를 출력할 목적으로 사용하는 클래스, 문자열을 출력하는 뷰
- TextView 이외에도 다양한 클래스가 존재
[레이아웃 클래스에 뷰 포함]
객체의 계층 구조에서 중요한 역할을 하는 것이 레이아웃 클래스임
- 레이아웃 클래스만 사용
- 아래 코드와 같이 작성한 레이아웃 XML 파일을 액티비티 화면에 출력하면 아무것도 나오지 않음
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
- 레이아웃 클래스에 뷰 포함
- ViewGroup 클래스의 하위인 레이아웃 클래스는 화면 자체가 목적이 아니라 다른 뷰 (TextView, ImageView 등) 객체 여러 개를 담아서 한꺼번에 제어할 목적으로 사용해야함
- 일종의 그릇 역할을 하는 셈임
- 따라서 다음처럼 레이아웃 클래스에 다른 뷰를 포함해 화면을 구성
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button // 버튼 2개 생성
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON1" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON2" />
</LinearLayout>
레이아웃 중첩
뷰의 계층 구조는 레이아웃 객체를 중첩해서 복잡하게 구성 가능
예를 들어 그림과 같은 화면을 출력해야 한다고 가정해보자.
- 버튼을 4개 출력하는 단순한 화면
- 이렇게 화면을 구성하려면 Button 객체가 4개 필요
- 이 버튼 4개를 하나의 레이아웃에 추가할 수도 있지만 다음처럼 중첩해서 구성 가능
👀 레이아웃 중첩 코드 보기
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON1" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON2" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON4" />
</LinearLayout>
</LinearLayout>
레이아웃 XML의 뷰를 코드에서 사용하기
뷰의 구조를 이해했다면 이제 어떻게 작성하는지 보겠다.
[화면 출력 순서]
1) 화면 구성을 레이아웃 XML 파일에 작성하고
2) 액티비티에서 setContentView()
함수로 XML 파일을 지정하면
3) 화면을 출력
[id 부여 전]
예를 들어 레이아웃 XML 파일에 다음처럼 작성했다면 화면에 “hello”라는 문자열을 출력하려면,
XML 태그로 입력한 TextView 객체가 생성되고 그 객체의 내용이 화면에 출력됨
👀 XML에 구현한 텍스트 뷰 객체 코드 보기
<TextView android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”hello” />
[id 부여]
그런데 때로는 이렇게 XML에 선언한 객체를 코드에서 사용해야 할 때 존재
위의 코드의 문제는 우리가 직접 생성한 객체가 아니므로 이름이 없어서 지칭할 수가 없다는 것임
➡ 각 객체를 어떻게 부를 것인지 식별자 id를 부여하고 그 식별자로 객체를 얻어 와야 함
➡ id는 꼭 지정해야 하는 속성은 아니며 레이아웃 XML에 선언한 뷰를 구별할 필요가 없을 때는 생략 가능
id 속성값은 “@+id/text1”
형태로 추가
➡ 이처럼 XML에 id 속성을 추가 하면 자동으로 R.java 파일에 상수 변수로 추가됨
➡ XML 속성값이 @로 시작하면 R.java 파일을 의미
👀 id 속성 부여 코드 보기
<TextView
// text1이 id값, 이 값은 식별자로 이용할 것이므로 앱에서 유일해야함
android:id=”@+id/text1”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”hello” />
[id 사용 1: 상수 변수]
이제 코드에서 R.java 파일의 상수 변수로 객체를 얻을 수 있음
이때 ```findViewById() 함수를 이용
setContentView()```: 액티비티의 화면을 출력하는 함수
➡ 이 함수를 호출하는 것만으로도 XML의 내용이 액티비티 화면에 출력됨
➡ 화면에 뷰의 내용이 나왔다는 것은 뷰 객체가 생성되었다는 것을 의미
이렇게 생성된 뷰 객체를 findViewById(R.id.text1)
처럼 가져오면 됨
👀 코드에서 XML에 입력한 객체 코드 보기
// XML 화면 출력
setContentView(R.layout.activity_main)
// id값으로 뷰 객체 획득
val textView1: TextView = findViewById(R.id.text1)
[id 사용 2: 제네릭으로 명시]
findViewById()
함수로 얻은 뷰 객체의 타입을 제네릭으로 명시해도 됨
👀 제네릭으로 가져온 뷰 객체 코드 보기
// XML 화면 출력, 뷰 객체 생성 완료
setContentView(R.layout.activity_main)
// id값으로 뷰 객체 획득
val textView1 = findViewById<TextView>(R.id.text1)
📜 굳이 코드에서 그 객체를 가져오는 이유 보기
레이아웃 XML에 구현한 대로 뷰가 화면에 나온다면 굳이 코드에서 그 객체를 가져와야할 필요가 있을까요?
자주 필요한가요?
화면이야 XML에 구현한 대로 잘 나오겠지만 XML에 입력한 뷰 객체를 코드에서 적절하게 이용해야 하므로 자주 사용합니다.
예를 들어 XML에 구현한 대로 텍스트 뷰가 “hello”라는 문자열을 출력하는데 만약 화면을 출력한 이후에 해당 문자열을 “world”라고 바꾸고 싶다면 어떻게 해야 할까요?
이럴 때는 코드에서 문자열을 출력하는 뷰 객체를 이용해야 합니다.
또, 특정 뷰 객체에 이벤트를 추가할 때도 필요합니다.
뷰의 크기를 지정
뷰를 레이아웃 XML에 등록하여 화면을 구성할 때 생략할 수 없는 속성이 바로 크기임
뷰가 화면에 나올 때 어떤 크기로 보여야 하는지는 필수 정보이며,
이 크기를 설정하는 속성은 layout_width
, layout_height
임
코드에서 layout_width, layout_height 속성을 이용해 TextView를 얼마만큼의 크기로 화면에 출력할 것인지를 지정
<TextView
android:id=”@+id/text1”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”hello” />
[크기를 나타내는 속성값]
다음 3가지 중 하나를 선언
- 수치
- 가로세로 크기를 100px처럼 수치로 지정 가능
- 이때 단위는 생략할 수 없으며 px, dp 등의 단위를 사용
- match_parent
- 부모의 크기 전체 크기
- 뷰 객체는 계층 구조로 이용하므로 어떤 뷰의 크기가 match_parent이면 자신보다 상위 계층의 크기를 뜻함
- wrap_content
- 자신의 콘텐츠를 화면에 출력할 수 있는 적절한 크기
- 예를 들어 TextView에 “hello”라는 문자열을 대입하고 크기를 wrap_content로 지정했다면 이 문자 열이 출력될 정도의 크기로 설정됨
- 만약 문자열이 길어지거나 글꼴이 커지면 뷰 크기도 따라서 커짐
👀 크기 지정의 예 코드 보기
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:orientation=”vertical”
android:background=”#ffff00”>
<Button
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”BUTTON1”
android:backgroundTint=”#0000ff” />
<Button
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:text=”BUTTON2”
android:backgroundTint=”#ff0000” />
</LinearLayout>
실행 결과