본문 바로가기
안드로이드

[안드로이드 #1] 안드로이드 시작 (하)

by algosketch 2021. 3. 1.

목차

  • 안드로이드 개발자 페이지
  • 안드로이드 4대 구성 요소
  • 프로젝트 만들기
  • 안드로이드 폴더 구조
  • Layout
  • View

 이 글은 [안드로이드 #1] 안드로이드 시작 (상)에 이어서 작성되었습니다. Layout 중간부터 시작합니다.

 - Layout

 Layout에는 여러 가지가 있습니다. 예를 들어 LinearLayout, TableLayout, RelativeLayout, ConstraintLayout 등이 있습니다. 그 중 LinearLayout과 ConstraintLayout 위주로 살펴볼 예정입니다. 프로젝트를 생성하면 자동으로 생성되는 코드에는 ConstraintLayout가 기본입니다. 그 이유는 아마 ConstraintLayout이 대부분의 경우에서 성능이 가장 좋기 때문이 아닐까 합니다. Layout 이나 View 하나를 만들 때마다 객체가 하나씩 생기는데 ConstraintLayout의 경우 다른 Layout을 이용하는 것보다 객체가 적어집니다.

기본 생성 코드

 

 1) LinearLayout

 가장 간단하게 사용할 수 있는 Layout은 LinearLayout이 아닐까 합니다. LinearLayout은 차례대로 View들을 쌓는 레이아웃입니다. 그렇기 때문에 가로로 배치할 것인지, 세로로 배치할 것인지 정해주어야 하죠. orientation 속성이 필수 속성입니다. vertical(세로)와 horizontal(가로)로 설정이 가능합니다.

 기본 생성 코드를 LinearLayout 버전으로 바꾸어 구현해 보도록 하겠습니다.

 

LinearLayout 1

 orientation을 세로로 지정해준 모습입니다. 그런데 아직 View가 하나라 특징을 확인할 수 없습니다. View를 두개 배치해 보도록 하겠습니다.

 

LinearLayout 2

 LinearLayout 에 텍스트뷰 두 개를 배치한 모습입니다. 구분의 편의를 위해 배경색을 넣었습니다. vertical로 지정했기 때문에 세로로 차곡차곡 쌓이는 모습입니다. 그리고 LinearLayout에서 자주 쓰이는 속성 중 하나인데, View에 weight라는 속성이 있습니다. 이 속성은 해당 View가 차지할 수 있는 공간 중에서 weight만큼의 비율만큼 차지하겠다는 뜻입니다. 위 예제에서는 초록색 텍스트뷰에 weight 1, 파란색 텍스트뷰에 weight 2 를 지정하여 1:2 비율로 나타납니다. 이 속성을 적용하려면 가로일 경우 width, 세로일 경우 height의 길이를 0으로 설정해야 합니다. 원래는 Layout에 orientation 속성을 지정하지 않으면 빨간 줄이 떠야 하는데 안드로이드 스튜디오 버전이 업데이트 되면서 디폴트 속성이 지정된 건지 orientation 속성을 빼먹어도 오류가 뜨지 않습니다.

 LinearLayout 의 특징에 대해 알아보았습니다. 간단한 레이아웃의 경우 LinearLayout으로 쉽게 구현이 가능하다는 것도 알게 되었을 것입니다. 하지만 조금만 레이아웃이 복잡해지더라도 LinearLayout을 사용하지 못 하는 것 아닐까요? 예를 들면 다음과 같은 화면을 구현할 수 있을까요?

LinearLayout 3


 성능은 Constraint보다 떨어지지만 LinearLayout으로도 복잡한 레이아웃 구성이 가능합니다. Layout을 중첩시키면 됩니다.

LinearLayout 4

 위와 같이 레이아웃을 중첩시키면 복잡한 레이아웃도 구성이 가능합니다. 다만 중첩시키는 과정에서 레이아웃이 하나 더 필요하기 때문에 효율적이지 못 합니다.

 2) ConstraintLayout

 ConstraintLayout은 RelativeLayout의 상위 호환 격입니다. ConstraintLayout이 있기 대문에 RelativeLayout은 사용한 필요가 없습니다. ConstraintLayout은 View 사이의 관계를 설정하여 UI를 배치합니다. LinearLayout으로 구현했던 것을 다시 ConstraintLayout으로 바꾸어 보도록 하겠습니다.

ConstraintLayout 1

 LinearLayout과는 다르게 동일한 속성만 가지고는 붉은 글씨로 표시되는 것이 보입니다. 필수 속성인 관계 속성을 설정하지 않았기 때문입니다. 가로위치와 세로위치를 어느 지점에 배치해야할 지 유추할 수 있으면 관계 설정이 제대로 된 것입니다. 제대로 관계 설정은 하여 첫 번째 화면과 같은 상태로 만들어 보도록 하겠습니다.

ConstraintLayout 2

 위 코드에서는
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
 이 두 가지 속성으로 세로부분에 대한 관계만 설정된 상태입니다. 가로 위치에 대한 정보가 없죠. 하지만 이 텍스트뷰는 가로의 크기가 화면 전체를 차지하기 때문에 별도로 가로 위치를 지정하지 않아도 어떻게 배치해야할지 유추가 가능합니다. app:layout_constraintTop_toTopOf="parent" 의 의미는 이 뷰의 top을 부모의 top에 붙여라 라는 의미입니다. 만약 app:layout_constraintBottom_toBottomOf="parent" 이 속성을 지우면 뷰는 상단에 달라붙게 됩니다. 이것은 Constraint의 중요한 특징인데요, 양쪽 방향으로 관계 설정이 되어 있을 때 레이아웃은 그 중간 지점에 뷰를 배치합니다. 그래서 위 아래 두 방향으로 관계 설정은 한 텍스트뷰가 화면의 중간 위치에 배치되는 것이지요.

ConstraintLayout 3

 위 예제처럼 app:layout_constraintTop_toTopOf="@id/tv_left" (View의 top을 tv_left의 top 부분에 배치한다.)를 이용하여 상단의 위치를 나란히 배치할 수 있습니다. 이 때 다른 뷰와의 관계를 설정하려면 해당 뷰에 id가 있어야하고 그 id를 참조하여 설정이 가능합니다.

ConstraintLayout 4

 관계 설정에 따라 위처럼 배치하는 것도 가능합니다.

 LinearLayout과 ConstraintLayout에 대해 알아보았습니다.

 RelativeLayout 또한 ConstraintLayout과 비슷한 특징을 가지고 있습니다. 계산기같은 레이아웃은 TableLayout을 이용하는 것이 적절할 것 같습니다. TabLayout과 ViewPager2를 이용하면 아래와 같은 화면도 만들 수 있습니다.

ViewPager2

 

 - View

 Layout을 설명하면서도 자주 등장했던 View입니다. 참고로 Layout도 View에 포함됩니다. View 역시 종류가 굉장히 많기 때문에 모두 설명할 수는 없고 몇 가지만 살펴보도록 하겠습니다.

TextView

 위에서 살펴봤던 코드에서 몇 가지 속성을 준 결과입니다. marginTop과 padding, textSize 를 바꿔주었습니다. 그 중 margin과 padding은 모든 View에서 사용할 수 있는 속성입니다. (TMI : 아마 웹 css를 해보신 분들이라면 별도의 설명 없이도 사용 가능할 것이라 생각됩니다. 다만 웹과 다른 점은 웹은 margin끼리 공간이 겹쳐져 양쪽 뷰에 24px만큼 마진을 설정해도 24px만 적용되지만 안드로이드에서는 48px만큼 적용됩니다.) margin은 다른 뷰들과 얼마나 떨어뜨릴 지 정하는 속성으로 위 코드에서는 marginTop으로 16dp를 주어 위에 있는 텍스트뷰와 16dp만큼의 간격을 벌렸습니다. padding은 뷰의 테두리와 뷰의 내용 사이에 간격을 두는 것입니다. 위 코드에서는 8dp의 간격을 두어 뷰의 테두리가 글씨와 너무 가깝지 않도록 공간을 두었습니다. 계속해서 등장하는 layout_widthlayout_height는 각각 가로와 세로 길이를 설정하는 속성입니다. 길이를 숫자 말고도 적용할 수 있는 중요한 두 가지 옵션이 있습니다. wrap_content와 match_parent입니다. wrap_content의 경우 View 내부 내용의 크기에 View의 크기를 맞추는 것이고, match_parent는 자신의 부모에 해당하는 뷰의 크기에 맞추는 것입니다. 위 코드에서 TextView들의 부모는 ConstraintLayout으로 화면 전체가 됩니다.
 안드로이드에서는 픽셀(px)을 사용하지 않고 dp라는 단위를 사용합니다. 안드로이드에서는 기기마다 해상도가 다르기 때문에 그것을 어느정도 보정해준 값이 dp라고 생각하시면 됩니다. 단 한 가지만 다른 단위를 사용하는데, textSize만 sp라는 단위를 사용합니다. 그래서 예제에서는 textSize를 24sp로 지정하여 글씨 크기를 키웠습니다. 참고로 24dp로 설정해도 같은 결과가 나옵니다.
 TextView에서 사용할 수 있는 속성으로 TextStyle(굵기, 이탤릭체), TextColor 등도 있습니다.

EditText

 EditText는 사용자가 글자를 입력할 수 있도록 제공해주는 View입니다. TextView와 마찬가지로 글자에 대한 속성을 지정할 수 있습니다. EditText의 주요 속성은 hint와 inputType이 있습니다. hint는 무엇을 입력하면 되는 지 안내 문구를 입력할 수 있습니다. 이 문구는 한 글자라도 작성하면 지워집니다. inputType은 처음 올라오는 자판의 종류(한글, 숫자, 영어 등)를 정해주고, 만약 속성이 비밀번호일 경우 자동으로 비밀번호를 가려줍니다. 사용자와 개발자 모두에게 편리한 속성입니다. 비밀번호 뿐만 아니라 날짜, 이메일을 입력하기에 적절한 양식도 줄 수 있습니다.

ImageView

 ImageView는 이미지를 출력할 수 있는 View입니다. src로 이미지 파일을 지정할 수 있습니다. 이미지 파일은 drawable 폴더에 저장합니다. 저는 별도로 지정할 이미지를 준비하지 않아 안드로이드 런쳐 이미지를 가져와 봤습니다.

Button 1

 Button은 버튼 클릭시 이벤트를 발생시킬 수 있는 가장 기본적인 View입니다. 이벤트를 발생시키는 코드를 작성하는 방법은 나중에 따로 다루도록 하겠습니다. 위 화면에 보이는 버튼은 기본적인 버튼의 모습인데 일단 너무 못 생겼습니다. 이럴 때 background 속성을 이용하여 button의 모습을 바꿔주면 됩니다. 웬만한 UI는 xml 코드로 그린 그림으로 제작할 수 있습니다. xml로 그림 그리는 방법은 기회가 되면 하겠지만 따로 설명하지 않을 예정이라 구글링으로 찾아보셔야할 것 같습니다.
 xml로 그림을 그리는 아래 코드는 drawable 폴더에서 New -> Drawable Resource File 을 선택하여 만들 수 있습니다.

xml 1

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <stroke android:width="2dp"
        android:color="#3971AF"/>
    <solid android:color="@color/white"/>
    <corners android:radius="16dp"/>
</shape>

 티스토리 블로그 소스코드에 xml코드 하이라이팅 기능이 없어서 최대한 비슷한 html로 적용해 보았습니다... 위 코드는 지금 하고 있는 프로젝트에 적용된 버튼 디자인 중 하나로 이 글을 못 보시겠지만 디자이너분께 감사드립니다. 꾸벅(-_)

버튼 2

 위 코드는 xml로 만든 그림을 background 속성으로 지정한 결과입니다. 제 여자친구만큼은 아니지만 먼저 만들었던 버튼보다 훨씬 이쁩니다 ㅎㅎ (아 여자친구 없었지...) 만약 버튼의 배경이 제대로 적용되지 않는다면 <Button/> 대신 <androidx.appcompat.widget.AppCompatButton/>를 사용해주세요.

 자세한 설명은 한 것은 위 네 개 뷰이지만(사실 위 네 개에 대해서도 설명할 수 있는 것들이 더 있습니다.) 훨씬 더 더 많은 뷰들이 있습니다.

SeekBar
ProgressBar

 만약 원하는 뷰가 없을 경우 직접 만드는 것도 가능합니다. 이를 커스텀 뷰(Custom View)라고 합니다.

CustomView

 위 이미지는 제가 만든 커스텀 뷰입니다. SeekBar를 상속받아 만든 뷰이고 드래그시 온도 조절이 가능합니다. 커스텀뷰 자체로도 개발이 쉽지가 않지만 SeekBar같은 경우 버그가 있어서 더더욱 커스텀 구현이 어렵습니다. 아무튼 직접 뷰를 만드는 것도 가능합니다!! 아 온도계 디자인도 버튼과 같은 디자이너 분이 주신 겁니다. 디자이너 분 감사합니다 ㅎㅅㅎ 참고로 온도계 배경도 xml로 만들었습니다. 아래 이미지는 xml로 가능한 것이 생각보다 많다는 것을 알려드리기 위한 것입니다.

xml 2

 카카오톡 친구 목록, 페이스북 피드 등 같은 형식으로 비슷한 데이터들을 출력할 수 있도록 만드는 RecyclerView라는 것도 있습니다. 이 View는 중요하지만 설명해야할 분량도 많고 구현 난이도도 높기 때문에 따로 하나의 강의로 만들어 설명할 예정입니다.

 일정 단위의 개발을 완료했다면 깃 허브에 저장해야 합니다. git은 버전 관리 시스템, github는 git으로 관리되고 있는 프로젝트를 올리는 웹 사이트입니다. github같은 사이트를 원격 저장소(remote repository)라 부릅니다. git의 주요 기능은 다음과 같습니다.
 commit : 현재 코드를 로컬(개인 컴퓨터)에 기록
 push : commit 내역을 github에 업로드
 pull : 업로드 되어 있는 코드를 다운로드

 중간중간에 commit을 해두시면 나중에 현재 코드와 과거 코드와 비교가 가능하고 필요하면 롤백도 가능합니다. 지금부터 commit 후 push하도록 하겠습니다. 여러분들은 과제를 완료한 뒤 따라해 주세요. 저도 과제 내용을 구현 후 github에 올렸습니다. 만약 과제가 너무 어렵다면 제 코드를 참고 하셔도 되고 구글링하셔도 됩니다. 혹은 직접 물어보셔도 됩니다.

github 1

 강의 (상)편에서 정상적으로 프로젝트를 만들었다면 commit 메뉴가 생깁니다.

github 2

  commit 메시지를 입력하고 commit을 눌러줍니다. 아마 경고창이 뜰 텐데 무시하고 commit을 눌러주세요.

github 3

 마지막으로 push를 눌러주시면 끝입니다.

 첫 번째 과제입니다. 아래와 같은 화면을 최대한 비슷하게 만들어 보세요!! 기능은 구현하실 필요 없이 화면만 아래와 같이 구성하시면 됩니다. 완성 후 개인 깃 허브에 올려주세요. 예시 코드는 이 링크에서 확인하실 수 있습니다.

첫 번째 과제

과제에 필요한 이미지 파일입니다. drawable폴더에 복사 후 사용하시면 됩니다.

btn_background.xml
0.00MB
edit_text_background.xml
0.00MB

 

 개인적인 생각으로, 뒤에서 돌아가는 코드가 무엇이든 화면 구성을 할 줄 알아야 자신감이 생기고 프로젝트를 진행할 수 있을 거라는 생각에 UI의 종류와 배치하는 방법을 먼저 다뤄봤습니다. 다음 강의에서는 직접 코드를 수정하여 이벤트도 발생시키는 예제를 만들어 보도록 하겠습니다.

다소 길었던(?) 첫 번째 안드로이드 강의를 마치겠습니다. 질문이나 궁금한 점은 댓글로 주셔도 되고 스터디방이나 개인 연락처로 주셔도 됩니다.