[Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 뷰를 이용한 화면 구성
안드로이드 앱 프로그래밍에서 화면을 구성하는 방법으로는 액티비티 코드와 레이아웃 XML 파일을 사용하는 두 가지 방법이 있다. 액티비티 코드로는 직접 뷰 객체를 생성하고 배치하며, XML 파일로는 태그를 이용해 화면을 구성한다. 뷰 클래스는 View의 하위 클래스로, TextView, ImageView, Button 등 다양한 뷰를 포함한다. 뷰 바인딩을 통해 레이아웃 XML 파일에 선언한 뷰 객체를 코드에서 쉽게 사용할 수 있으며, 이를 위해 build.gradle 파일에 viewBinding을 설정해야 한다. 뷰 바인딩을 사용하면 findViewById() 함수를 대체해 더 간편하게 뷰 객체를 다룰 수 있다.
Jul 04, 2024
🌼화면을 구성하는 방법
💡액티비티-뷰 구조
- 안드로이드 앱은 액티비티, 서비스, 브로드캐스트 리시버, 콘텐츠 프로바이더와 같은 컴포넌트를 조합해서 만든다.
- 앱에서 화면을 출력하고 싶다면 액티비티를 만들어야 한다.
- 사용자에게 보여줄 화면이 10개가 있다고 가정했을 때, 액티비티를 10개나 만들지 않고 프래그먼트나 컴포즈를 이용해 1개로 만들 수 있다.
- 액티비티에서 뷰로 화면을 구성하는 방법은 2가지이다.
- 액티비티 코드로 작성
- 레이아웃 XML 파일로 작성
💡액티비티 코드로 화면 구성하기
- 예를 들어 그림 하나와 텍스트를 화면에 출력한다고 해보자.
- 액티비티 코드의 경우화면 구성과 관련된 모든 내용을 직접 코드로 작성해야 한다.
- 먼저
TextView
클래스와ImageView
클래스 객체를 생성한다. 그리고 이를 화면에 배치하려면LinearLayout
클래스에 객체를 추가한 후,setContentView()
로 전달해 화면을 출력할 수 있다.
만약 호출하려는 함수가 고차함수이고, 마지막 전달 인자가 람다 함수면 소괄호를 생략해도 된다.
// 매개변수가 2개 이상인 함수 fun some(arg1: Int, arg2: ()->Unit, arg3: ()->Unit){ } // 해당 함수를 호출하는 방법 some(10, {println("hello")}, {println("world")}) // 성공 some(10, {println("hello")}) {println("world")} // 성공 some 10, {println("hello")}, {println("world")} // 오류 some (10), {println("hello")} {println("world")} // 오류
💡레이아웃 XML로 화면 구성하기
- 레이아웃 XML의 경우 화면을 구성하는 데 필요한
TextView
나ImageView
등을 XML의 태그로 명시해 화면을 구성하는 방법이다.
- XML을 이용해 화면을 구현하면, 코드에서 화면을 구현한 XMl을 명시해 어떤 화면을 출력할 지 알려줘야 한다.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 화면 출력 XML 명시 setContentView(R.layout.activity_main) } }
효율성을 고려한다면 XML 파일로 화면을 구현하는 것이 더 좋다.
액티비티에는 작성해야 할 코드가 많은데 화면을 구현하는 코드까지 길어지면 유지 보수 면에서 부담스럽기 때문이다.
🌼뷰 클래스
💡뷰 클래스의 기본 구조
- 액티비티 화면을 구성할 때 사용하는 클래스는 모두
View
의 하위 클래스다. View
: 모든 뷰 클래스의 최상위 클래스다. 액티비티는View
의 서브 클래스만 화면에 출력한다.ViewGroup
:View
의 하위 클래스지만 자체 UI는 없어서 화면에 출력해도 아무것도 나오지 않는다. 다른 뷰 여러 개를 묶어서 제어할 목적으로 사용한다.TextView
: 특정 UI를 출력할 목적으로 사용하는 클래스, 문자열을 출력하는 뷰다. 이외에도 다양한 클래스가 있다.
- 객체의 계층 구조에서 중요한 역할을 하는 것이 레이아웃 클래스다.
- 단순히
LinearLayout
태그만 작성하면 아무것도 화면에 나오지 않는다. 다른 객체 여러 개를 담아서 한꺼번에 제어하는 목적으로 사용할 수 있다. - 단순히 버튼을 4개 출력하는 화면을 생각해보면 Button 객체를 하나의 레이아웃에 추가할 수도 있지만 다음처럼 중첩해서 구성할 수도 있다.
LinearLayout
객체에 또 다른LinearLayout
객체를 포함하여 화면을 구성했는데, 이처럼 계층 구조로 만들어 이용하는 패턴을컴포지트 패턴
또는문서 객체 모델
이라고 한다.
💡레이아웃 XML의 뷰를 코드에서 사용하기
- XML에 선언한 객체를 코드에서 사용하려고 할 때, 직접 생성한 객체가 아니므로 이름이 없어서 지칭할 수가 없다.
- 이때 id 속성을 지정해서 사용할 수가 있다.
<TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hello" />
@
로 시작하면 R.java 파일을 의미한다. 따라서 위 표현식은 R.java 파일에 text1이라는 상수 변수를 추가하라는 의미다.//코드에서 XML에 입력한 객체 사용법 // XML 화면 출력 setContentView(R.layout.activity_main) // id값으로 뷰 객체 획득 val textView1: TextView = findViewById(R.id.text1) // 제네릭으로 명시해도 사용 가능 val textView2 = findViewById<TextView>(R.id.text1)
💡뷰의 크기를 지정하는 방법
- 뷰를 레이아웃 XMl에 등록하여 화면을 구성할 때 생략할 수 없는 속성이 크기다.
- 설정하는 속성으로는
layout_width
,layout_height
가 있다. - 크기를 나타내는 속성값에는
수치
,match_parent
,wrap_content
중 하나를 선언한다. 수치
의 경우 단위를 생략할 수 없으며 px, dp 등의 단위를 사용한다.match_parent
는 부모의 크기 전체로, 자신보다 상위 계층의 크기를 뜻한다.wrap_content
는 자신의 콘텐츠를 화면에 출력할 수 있는 적절한 크기를 의미한다. 문자열이 “hello”라면 “hello”가 출력될 정도의 크기로 설정된다.
💡뷰의 간격 설정
- 뷰의 간격은
margin
과padding
속성으로 설정한다. margin
은 뷰와 뷰 사이의 간격이며padding
은 뷰의 콘텐츠와 테두리 사이의 간격이다.- 기본적으로 네 방향 모두 같은 크기로 설정되며, 특정 방향의 간격만 설정하고 싶다면
paddingLeft, paddingRight, paddingTop, paddingBottom
과 같이 따로 지정할 수 있다.
💡뷰의 표시 여부 설정
visibility
속성은 뷰가 화면에 출력되어야 하는지를 설정한다.- 기본값은
visible
이며invisible
,gone
을 설정할 수 있다.invisible
은 보이지 않지만 자리는 차지하며,gone
은 보이지 않고 자리를 차지하지 않는다.
XML이 아닌 코드에서 뷰의 속성을 설정하려면 해당 뷰의
visibility
속성값을 View.VISIBLE
이나 View.INVISIBLE
로 설정한다.
이 때, 세터 함수를 호출하지 않아도 된다. 코틀린의 변수는 자바와 다르게 필드가 아니라 프로퍼티이므로 변수에 세터와 게터가 내장되어 있다.
따라서 다음 두개의 코드는 동일한 동작을 한다.
targetView.visibility(View.VISIBLE) targetView.setVisibility(View.VISIBLE)
🌼기본적인 뷰 살펴보기
💡텍스트 뷰
TextView
는 문자열을 화면에 출력하는 뷰다.android:text
:TextView
에 출력할 문자열을 지정한다. 문자열을 대입하거나 문자열 리소스를 지정할 수 있다.android:textColor
: 문자열의 색상을 지정한다. 값은 16진수 RGB 형식을 사용한다.android:textSize
: 문자열의 크기를 지정한다. 값은 숫자를 사용하며 단위(px, dp, sp)는 생략할 수 없다.android:textStyle
: 문자열의 스타일을 지정한다. 값은bold, italic, normal
중에서 선택한다.android:autoLink
: 출력할 문자열을 분석해 특정 형태의 문자열에 자동 링크를 추가해 준다. 값은web, phone, email
등을 사용할 수 있으며 여러 개를 함께 설정하려면 | 기호로 연결한다.android:maxLines
: 문자열을 특정 줄까지만 나오게 설정할 수 있다. 값은 정수를 사용한다.android:ellipsize
:maxLines
속성을 이용할 때 출력되지 않은 문자열이 더 있다는 것을 표시하는 줄임표(…)를 출력하는 속성이다. 값으로는end, middle, start
등이 있다.
💡이미지 뷰
ImageView
는 이미지를 화면에 출력하는 뷰다.android:src
:ImageView
에 출력할 이미지를 설정한다. 리소스 이미지, 파일 이미지, 네트워크 이미지 등을 출력할 수 있다.android:maxWidth, android:maxHeight, android:adjustViewBounds
:ImageView
가 출력하는 이미지의 최대 크기를 지정한다.maxWidth, maxHeight
속성은adjustViewBounds
속성과 함께 사용해야 하며, 이 속성을true
로 설정하면 이미지의 가로세로 길이와 비례해 뷰의 크기를 맞춘다.
뷰에 넣을 이미지의 크기가 다양하다면 이미지와 뷰의 크기가 맞지 않는 상황이 발생할 수 있기 때문에 사용한다.
💡버튼, 체크박스, 라디오버튼
Button
은 사용자 이벤트를 처리하고CheckBox
는 다중 선택을,RadioButton
은 단일 선택을 제공하는 뷰다.
RadioButton
은RadioGroup
과 함께 사용하며 그룹으로 묶은 라디오 버튼 중 하나만 선택할 수 있다.
💡에디트 텍스트
EditText
는 사용자가 글을 입력할 수 있는 뷰다.android:lines, android:maxLines
:EditText
는 한 줄 입력 크기로 출력되었다가 사용자가 엔터를 누르면 아래로 늘어난다.lines
속성을 설정하면 설정한 크기로 고정된다.maxLines
속성을 설정하면 처음에는 한 줄 입력 크기로 출력되다가 사용자가 엔터를 누르면 설정한 크기까지만 늘어난다.android:inputType
:EditText
에 글을 입력할 때 올라오는 키보드를 지정한다. 키보드로 한 줄 입력을 강제하거나 전화번호 입력 모드 등을 지정할 때 사용한다.
속성값 | 설명 |
none | 입력 유형을 지정하지 않은 상태. 모든 문자 입력 가능하며 줄바꿈 가능 |
text | 문자열 한 줄 입력 |
textCapCharacters | 대문자 입력 모드 |
textapWrods | 각 단어의 첫 글자 입력 시 키보드가 자동으로 대문자 입력 모드 |
textCapSentences | 각 문단의 첫 글자 입력 시 키보드가 자동으로 대문자 입력 모드 |
textMultiLine | 여러 줄 입력 가능 |
textNoSuggestions | 단어 입력 시 키보드의 추천 단어를 보여주지 않음 |
textUri | URL 입력 모드 |
textEmailAddress | 이메일 주소 입력 모드 |
textPassword | 비밀번호 입력 모드로 입력한 문자를 점으로 표시. 키보드는 영문자와 숫자, 특수 키만 표시 |
textVisiblePassword | textPassword와 같으며 입력한 문자 표시 |
number | 숫자 입력 모드 |
numberSigned | number와 같으며 부호 키인 마이너스(-) 입력 가능 |
numberDecimal | number와 같으며 소숫점 입력 가능 |
numberPassword | 숫자 키만 입력 가능. 입력한 문자는 점으로 표시 |
phone | 전화번호 입력 모드 |
🌼뷰 바인딩
💡뷰 바인딩이란?
- 뷰 바인딩은 레이아웃 XML 파일에 선언한 뷰 객체를 코드에서 쉽게 이용하는 방법이다.
- 레이아웃 XMl 파일에 등록한 뷰는
findViewById()
함수로 얻어서 사용해야 한다. - 하지만 이 작업은 수많은 뷰 객체들을 함수로 하나하나 다져와야하는 단점이 있다.
- 이 문제를 뷰 바인딩을 통해 해결할 수 있다.
- 우선 뷰 바인딩을 사용하려면
build.gradle
파일의android
영역에buildFeatures
를 선언한다. 그리고 그 안에 바인딩을 적용하라는 의미로viewBinding = true
를 설정한다.
android{ (...생략...) viewBinding.isEnabled = true }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" (...생략...) tools:viewBindingIgnore="true">
- 자동으로 만들어진 클래스의
inflate()
함수를 호출하면 바인딩 객체를 얻을 수 있다. 이때 인자로layoutInflater
를 전달한다 - 바인딩 객체의
root
프로퍼티에는 XML의 루트 태그 객체가 자동으로 등록되므로 액티비티 화면 출력은setContentView()
함수에binding.root
를 전달하면 된다.
// 바인딩 객체 이용법 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 바인딩 객체 획득 val binding = ActivityMainBinding.inflate(layoutInflater) // 액티비티 화면 출력 setContentView(binding.root) // 뷰 객체 이용 binding.visibleBtn.setOnClickListener{ binding.targetView.visibility = View.VISIBLE } binding.invisibleBtn.setOnClickListener{ binding.targetView.visibility = View.VISIBLE } } }
🏁결론
안드로이드 앱 프로그래밍에서 화면을 구성하는 방법으로는 액티비티 코드와 레이아웃 XML 파일을 사용하는 두 가지 방법이 있다. 액티비티 코드로는 직접 뷰 객체를 생성하고 배치하며, XML 파일로는 태그를 이용해 화면을 구성한다. 뷰 클래스는
View
의 하위 클래스로, TextView
, ImageView
, Button
등 다양한 뷰를 포함한다. 뷰 바인딩을 통해 레이아웃 XML 파일에 선언한 뷰 객체를 코드에서 쉽게 사용할 수 있으며, 이를 위해 build.gradle
파일에 viewBinding
을 설정해야 한다. 뷰 바인딩을 사용하면 findViewById()
함수를 대체해 더 간편하게 뷰 객체를 다룰 수 있다.Share article