[Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 뷰를 이용한 화면 구성

안드로이드 앱 프로그래밍에서 화면을 구성하는 방법으로는 액티비티 코드와 레이아웃 XML 파일을 사용하는 두 가지 방법이 있다. 액티비티 코드로는 직접 뷰 객체를 생성하고 배치하며, XML 파일로는 태그를 이용해 화면을 구성한다. 뷰 클래스는 View의 하위 클래스로, TextView, ImageView, Button 등 다양한 뷰를 포함한다. 뷰 바인딩을 통해 레이아웃 XML 파일에 선언한 뷰 객체를 코드에서 쉽게 사용할 수 있으며, 이를 위해 build.gradle 파일에 viewBinding을 설정해야 한다. 뷰 바인딩을 사용하면 findViewById() 함수를 대체해 더 간편하게 뷰 객체를 다룰 수 있다.
DriedPollack's avatar
Jul 04, 2024
[Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 뷰를 이용한 화면 구성

🌼화면을 구성하는 방법

💡액티비티-뷰 구조

  • 안드로이드 앱은 액티비티, 서비스, 브로드캐스트 리시버, 콘텐츠 프로바이더와 같은 컴포넌트를 조합해서 만든다.
  • 앱에서 화면을 출력하고 싶다면 액티비티를 만들어야 한다.
    • 사용자에게 보여줄 화면이 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의 경우 화면을 구성하는 데 필요한 TextViewImageView등을 XML의 태그로 명시해 화면을 구성하는 방법이다.
  • XML을 이용해 화면을 구현하면, 코드에서 화면을 구현한 XMl을 명시해 어떤 화면을 출력할 지 알려줘야 한다.
    • class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 화면 출력 XML 명시 setContentView(R.layout.activity_main) } }
      💡
      효율성을 고려한다면 XML 파일로 화면을 구현하는 것이 더 좋다. 액티비티에는 작성해야 할 코드가 많은데 화면을 구현하는 코드까지 길어지면 유지 보수 면에서 부담스럽기 때문이다.
 

🌼뷰 클래스

💡뷰 클래스의 기본 구조

  • 액티비티 화면을 구성할 때 사용하는 클래스는 모두 View의 하위 클래스다.
    • notion image
    • View : 모든 뷰 클래스의 최상위 클래스다. 액티비티는 View의 서브 클래스만 화면에 출력한다.
    • ViewGroup : View의 하위 클래스지만 자체 UI는 없어서 화면에 출력해도 아무것도 나오지 않는다. 다른 뷰 여러 개를 묶어서 제어할 목적으로 사용한다.
    • TextView : 특정 UI를 출력할 목적으로 사용하는 클래스, 문자열을 출력하는 뷰다. 이외에도 다양한 클래스가 있다.
  • 객체의 계층 구조에서 중요한 역할을 하는 것이 레이아웃 클래스다.
    • 단순히 LinearLayout 태그만 작성하면 아무것도 화면에 나오지 않는다. 다른 객체 여러 개를 담아서 한꺼번에 제어하는 목적으로 사용할 수 있다.
    • 단순히 버튼을 4개 출력하는 화면을 생각해보면 Button 객체를 하나의 레이아웃에 추가할 수도 있지만 다음처럼 중첩해서 구성할 수도 있다.
      • notion image
    • LinearLayout 객체에 또 다른 LinearLayout 객체를 포함하여 화면을 구성했는데, 이처럼 계층 구조로 만들어 이용하는 패턴을 컴포지트 패턴 또는 문서 객체 모델이라고 한다.

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

  • XML에 선언한 객체를 코드에서 사용하려고 할 때, 직접 생성한 객체가 아니므로 이름이 없어서 지칭할 수가 없다.
    • 이때 id 속성을 지정해서 사용할 수가 있다.
      • <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hello" />
    • XML 속성값이 @로 시작하면 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”가 출력될 정도의 크기로 설정된다.

💡뷰의 간격 설정

  • 뷰의 간격은 marginpadding 속성으로 설정한다.
    • 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은 단일 선택을 제공하는 뷰다.
  • RadioButtonRadioGroup과 함께 사용하며 그룹으로 묶은 라디오 버튼 중 하나만 선택할 수 있다.

💡에디트 텍스트

  • 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 }
    • 이러면 레이아웃 XML 파일에 등록된 뷰 객체를 포함하는 클래스가 자동으로 만들어진다.
    • 어떤 레이아웃 XML 파일은 바인딩 클래스로 만들 필요가 없을 수 있다. 이때는 XML 파일의 루트 태그에 다음과 같이 속성을 추가한다.
      • <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" (...생략...) tools:viewBindingIgnore="true">
    • 자동으로 만들어지는 클래스의 이름은 레이아웃 XML 파일명을 따른다. 첫 글자를 대문자로 하고, 밑줄(_)은 빼고, 뒤에 오는 단어를 대문자로 만든 후 Binding이 추가된다.
  • 자동으로 만들어진 클래스의 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

More articles

See more posts

👨🏻‍💻DriedPollack's Blog