출처:http://www.edwith.org/boostcourse-android/project/5/content/4#summary



첫 번째 단계에서 만들 영화상세 화면이에요.

위쪽에 작은 영화 포스터가 보이고

오른쪽에 영화명, 관람등급 개봉일, 장르, 상영시간이 보이죠.

좋아요, 싫어요 아이콘과

좋아요 숫자, 싫어요 숫자도 보이네요.

그 아래에 보이는 것이 예매율, 평점 누적 관객 수에 대한 정보인데요.

가로방향으로 공간 분할을 하고 있죠.

가운데에는 평점을 보여주고 있는데

레이팅바라고 하는 것을 이용해서 보여주고 있어요.

그리고 평점 오른쪽에 숫자가 있고요.

화면을 아래쪽으로 좀 더 내려보면 줄거리, 감독, 배우에 대한 설명이 나와요.

제목 글자는 진하게 Bold 체로 보여주고 있네요.

가장 아래쪽에는 한줄평을 위해서 공간을 띄어놓으셔야 해요.

이 공간에는 두 번째 단계에서 한줄평 목록을 추가할 거예요.

지금은 공간만 띄어 놓으시면 돼요.

한줄평 작성하기와 모두 보기를 위한 버튼도 보이죠.

마지막 줄에는 SNS 아이콘 그리고 예매 버튼 같은 것들을 보실 수 있어요.



단일 레이아웃

1) 영화 상세 정보를 표시하기 위한 화면 레이아웃을 만듭니다.

  • 화면 레이아웃 구성은 아래 그림을 참조하세요.

2) 화면을 구성하기 위해서는 레이아웃과 위젯을 사용합니다. 종류는 아래와 같습니다.

  • 제약 레이아웃(ConstraintLayout), 리니어 레이아웃(LinearLayout), 상대 레이아웃(RelativeLayout) 등의 레이아웃
  • 이미지뷰(ImageView), 텍스트뷰(TextView) 등의 위젯
  • 평점에 사용되는 별의 경우 RatingBar 위젯 사용 (RatingBar 사용방법 : https://developer.android.com/reference/android/widget/RatingBar.html

3) 화면에 표시될 내용은 다음과 같습니다.

  • 영화 이미지와 영화 간단 정보(관람등급, 이름, 개봉일, 장르, 시간 등)
  • 좋아요/싫어요 아이콘과 예매율, 평점, 관객 수
  • 줄거리와 감독/출연 배우
  • 페이스북 등으로의 링크 이미지, 예매하기 버튼 표시

4) 한 줄 평을 표시할 공간을 만들어둡니다. (한 줄 평 데이터는 표시하지 않습니다.)







출처 : http://www.edwith.org/boostcourse-android/lecture/20421/


쉐이프 드로어블

쉐이프 드로어블은 XML로 도형을 그릴 수 있도록 합니다.

/res/drawable 폴더 안에 XML 파일을 만들고 최상위 태그를 <shape>로 바꾸면 도형 하나를 정의할 수 있습니다.

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:width="200dp" android:height="120dp"/>
    <stroke android:width="1dp" android:color="#0000ff"/>
    <solid android:color="#aaddff" />
    <padding android:bottom="1dp" />

</shape>

<shape> 태그에는 shape 속성이 들어갈 수 있으며 rectangle로 설정하면 직사각형, oval로 설정하면 타원, line으로 설정하면 선, ring으로 설정하면 고리 모양으로 그릴 수 있습니다.

도형의 테두리 선에 대해 굵기나 색상을 지정할 수도 있고 도형을 채우는 색상을 지정할 수도 있습니다.

<stroke> 태그는 <shape> 태그 안에 넣어서 테두리 선의 속성을 지정할 수 있으며 width는 선의 굵기, color는 선의 색상을 설정할 때 사용하죠. <solid> 태그는 도형의 안쪽을 채울 때 사용합니다.

배경색으로 그러데이션을 줄 때는 <gradient> 태그를 사용할 수 있습니다.

<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient
        android:startColor="#7288DB"
        android:centerColor="#3250B4"
        android:endColor="#254095"
        android:angle="90"
        android:centerY="0.5"
        />

    <corners android:radius="2dp" />

</shape>

<shape> 태그 안에 <gradient> 태그를 넣으면 그러데이션이 만들어지게 됩니다.

startColor에는 시작 부분의 색상, centerColor에는 가운데 부분의 색상, endColor에는 끝 부분의 색상을 지정할 수 있습니다.

위쪽에서부터 아래쪽으로 내려오면서 색상이 바뀌는 모양이 되는 거죠.


테두리만 있는 버튼 배경

<layer-list> 태그를 사용하면 여러 그래픽을 하나의 XML 파일에 넣을 수 있습니다.

<layout-list> 태그 안에는 <item> 태그가 여러 개 들어갈 수 있으며 <item> 태그 안에는 <shape> 태그가 들어갈 수 있어 각각을 도형으로 정의할 수 있습니다.

만약 버튼의 테두리만 보이게 하는 드로어블을 만들고 싶다면 도형 안쪽을 투명하게 채우고 테두리 선만 색상을 주면 됩니다. 그런데 이것을 두 개의 그래픽으로 정의할 수도 있습니다.

하나의 그래픽으로 정의할 것인지 아니면 여러 개의 그래픽으로 정의할 것인지는 선택의 문제이지만 여러 개의 그래픽으로 나누면 그래픽을 중첩시켜서 좀 더 예쁜 배경을 만들 수 있습니다.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <stroke android:width="1dp" android:color="#BE55DA" />
            <solid android:color="#00000000" />
        </shape>
    </item>

    <item android:top="1dp" android:bottom="1dp" 
android:right="1dp" android:left="1dp">
        <shape android:shape="rectangle">
            <stroke android:width="1dp" android:color="#BE55DA" />
            <solid android:color="#00000000" />
        </shape>
    </item>

</layer-list>

 

 


생각해보기

  1. 버튼의 테두리를 쉐이프 드로어블로 만들어 사용하면 포토샵으로 디자인한 버튼 배경 이미지를 사용하는 것에 비해어떤 장점이 생길까요?
    - 당연히 첫번째로는 포토샵에서 만든이미지를 따로 불러와서 쓸 필요가 없다는 것이고, 해상도가 딱맞아서 깨질일이 없다.
  2. 여러 종류의 쉐이프 드로어블을 만들고 그 중 하나를 화면에 들어있는 버튼들의 배경으로 설정할 수 있습니다. 이 상태에서 사용자가 여러 종류 중 하나를 선택하면 화면에 있는 모든 버튼의  배경을 바꾸도록 만들 수 있을까요? 이렇게 하면 버튼의 배경 스타일을 한꺼번에 바꾸는 효과가 있을까요?
    - ID로 일일히 찾아서 바꿔주면되는데 좀더 효과적인 방법이있을것같다.


출처 : http://www.edwith.org/boostcourse-android/lecture/20420/


상태 드로어블

상태 드로어블은 뷰의 상태에 따라 뷰에 보여줄 그래픽을 다르게 지정할 수 있도록 합니다.

/res/drawable 폴더 안에 새로운 XML 파일을 만들면 최상위 태그는 <selector>가 됩니다.

그 안에 <item> 태그를 넣을 수 있으며 drawable 속성에는 이미지나 다른 그래픽을 설정하여 화면에 보이도록 할 수 있습니다.

state_ 로 시작하는 속성은 상태를 나타내는데 예를 들어 state_pressed 속성은 눌린 상태를 의미하고 state_focused는 포커스를 받은 상태를 의미합니다.

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true"  
android:drawable="@drawable/ic_thumb_up_selected" />

    <item android:drawable="@drawable/ic_thumb_up" />

</selector>

상태 속성이 지정되지 않은 <item> 태그에는 drawable 속성에 ic_thumb_up 이미지가 설정되어 있으므로 디폴트 이미지로 보이게 됩니다.

state_pressed 속성이 설정된 <item> 태그에는 ic_thumb_up_selected 이미지가 설정되어 있으며 이 이미지는 뷰가 눌렸을 때 보이게 됩니다.

이렇게 만든 XML 파일은 뷰의 background 속성으로 설정될 수 있습니다.

/res/drawable 폴더 안에 thumb_up.xml 이라는 이름의 파일을 만들었다면 다음과 같이 버튼의 배경으로 설정할 수 있습니다.

<Button
    android:id="@+id/button"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:background="@drawable/thumb_up"
    />

 

 


생각해보기

  1. 소스 코드로 드로어블을 만드는 것보다 XML로 드로어블을 만들어 사용하면 얼마나 더 편리해지는 걸까요?
    - 확실히 편하다. 소스에서 조건문을걸거나 그럴필요없이 바로 xml에서 할수 있기 때문에 한눈에 알아보기 편하다.
  2. XML로 드로어블을 만들고 레이아웃의 배경으로 설정하면 카드 모양의 배경을 만들 수 있을까요?
    - 카드모양이라는게 명확하지는않지만 패턴이있는 무늬모양이라면 가능할것 같다.


출처 : http://www.edwith.org/boostcourse-android/lecture/17045/


텍스트뷰 (TextView)

프로젝트를 처음 만들었을 때부터 화면 레이아웃 안에는 텍스트뷰가 들어 있습니다.

텍스트뷰는 화면에 글자를 표시하도록 해줍니다.

텍스트뷰에 글자를 표시할 때는 text 속성에 직접 글자를 넣어줄 수도 있지만 /res/values 폴더 안에 들어있는 strings.xml 파일 안에 넣어둔 태그의 값으로 설정할 수도 있습니다.

다음과 같이 name 속성의 값을 strings.xml 파일 안에 넣어줍니다.

<resources>
  <string name="name">John</string>
</resources>

그러면 텍스트뷰의 text 속성 값으로 @string/name 을 넣어줄 수 있습니다.

이 방식은 다국어를 설정할 때도 유용합니다.

만약 /res/values-en 폴더와 /res/values-ko 폴더를 만들고 그 안에 strings.xml 파일을 같이 넣어주었다면 @string/name 으로 참조하는 글자는 단말의 로케일(Locale)에 따라 달라집니다.

단말이 한국어로 설정되어 있다면 /res/values-ko/strings.xml 파일 안에 들어있는 name 태그의 값을 가져오는 것이죠.

텍스트뷰에는 text속성과 함께 textColor, textSize, textStyle 속성도 많이 사용됩니다.

 

버튼 (Button)

버튼은 텍스트뷰를 상속하여 만들어졌기 때문에 XML 레이아웃에 들어있는 태그의 이름을 TextView에서 Button으로 바꾸기만 해도 버튼이 화면에 보이게 됩니다.

즉, 버튼은 텍스트뷰의 속성을 모두 가지고 있으면서 추가적인 기능이나 속성을 더 가지고 있습니다.

버튼은 다시 라디오버튼(RadioButton)이나 체크박스(CheckBox) 등으로 나누어 사용될 수 있습니다.

그중에서 라디오버튼은 라디오그룹(RadioGroup)을 이용해 하나의 그룹으로 묶어줄 수 있습니다.

남자와 여자를 선택하는 라디오버튼을 화면에 넣고 싶다면 다음과 같이 그룹으로 묶어줍니다.

<RadioGroup
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
>
<RadioButton
  android:id="@+id/radio1"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="남자" />
<RadioButton
  android:id="@+id/radio2"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="여자" />
</RadioGroup>


에디트텍스트 (EditText)

에디트텍스트는 입력상자의 역할을 합니다.

사용자가 입력한 글자를 받고 처리하는 기능을 제공하므로 상당히 많이 사용됩니다.

이 위젯에서 많이 사용되는 속성으로 inputType을 들 수 있습니다.

inputType은 어떤 유형의 글자를 입력할 지를 결정하는 속성으로 이 속성을 어떤 값으로 설정했는가에 따라 키패드의 형태가 달라집니다.

hint 속성을 설정하면 글자를 입력하지 않았을 때 희미하게 보이는 안내글을 표시해줍니다.

<EditText
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:inputType="number"
  android:hint="아이디" />


이미지뷰 (ImageView)

이미지뷰는 이미지를 보여줍니다.

프로젝트의 res 폴더 안에는 drawable 폴더가 들어있는데 이 폴더 안에 이미지 파일을 넣고 이미지뷰에 설정할 수 있습니다.

Drawable 폴더에 이미지를 넣을 때 이미지 파일의 이름은 소문자와 특수기호 중 언더스코어(_)만 넣을 수 있다는 점에 주의해야 합니다. 이미지 파일의 확장자는 jpg, png, gif 등이 가능하며 그중에서 png 형식의 이미지를 권장합니다.

예를 들어, drawable에 넣은 이미지 파일의 이름이 house.png라면 다음과 같이 src 속성으로 설정할 수 있습니다.

android:src="@drawable/house"

scaleType 속성은 이미지가 이미지뷰가 가지는 영역을 꽉 채울 것인지 아니면 이미지 원본의 크기대로 보여줄 것인지 등을 결정하는 데 사용됩니다. 직접 scaleType 속성의 값을 이것저것 바꾸어가면서 화면에 보이는 결과를 확인해보세요.

 

 


생각해보기

  1. 다른 사람들이 Play스토어에 올려놓은 앱의 화면에서 볼 수 있는 버튼이나 텍스트뷰에는 얼마나 많은 속성이 
    설정되어 있을까요?
    -쉬운 버튼은 가볍게 몇개정도만 되어있을수있지만 가능한속성값들이 엄청나게 많기때문에 그에따라서 또 다를것 같다.
  2. 버튼의 background 속성을 이용해 배경으로 이미지를 설정하면 이미지뷰의 src 속성을 이용해 
    이미지를 보여주었을 때와 다른 점이 있을까요?
    - 다음에 수정이 필요할때 수정하는방법에서 차이가 나는것 같다. 버튼자체를 수정하는것과 이미지뷰자체를 수정하는것
  3. 원본 이미지의 해상도가 각각 다른 여러 이미지를 하나의 이미지뷰에 번갈아 가면서 보여주려 할 때 
    이미지뷰의 
    scaleType 을 어떻게 설정해야 제대로 보여줄 수 있을까요?
    -fitCenter를 이용하여 해주면 가운데에서 딱맞게 fit을 해주어서 잘 보여줄수 있을것 같다.


출처 : http://www.edwith.org/boostcourse-android/lecture/17044/


프레임 레이아웃

프레임 레이아웃은 한 번에 하나의 뷰만 보여주는 레이아웃입니다.

가장 단순한 레이아웃이죠.

이 레이아웃에 뷰를 여러 개 추가했다면 그중 가장 나중에 추가한 뷰만 화면에 보이게 됩니다.

이런 특성 때문에 뷰들을 여러 개 담아놓고 중첩할 때 주로 사용됩니다.

아래쪽에 깔린 다른 뷰를 화면에 보여주고 싶다면 위쪽으로 뷰를 올려줄 수도 있고 보고자 하는 뷰 외의 다른 뷰들을 보이지 않게 할 수도 있습니다.

프레임 레이아웃을 이용한 뷰의 중첩 방식

가시성 속성의 사용

프레임 레이아웃 안에 중첩된 뷰들 중에서 하나만 보여주고 싶다면 가시성(visibility) 속성을 사용할 수 있습니다.

가시성(visibility) 속성의 값으로는 visible, invisible, gone이 있습니다. 보여주고 싶은 뷰의 visibility 속성값은 visible로 하고 보여주고 싶지 않은 뷰들은 invisible이나 gone으로 설정하면 visible로 지정한 뷰만 화면에 보이게 됩니다.

<FrameLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
>
<ImageView
  android:id="@+id/imageView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:src="@drawable/dream01"
  android:visibility="invisible" />
<ImageView
  android:id="@+id/imageView2"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:src="@drawable/dream02"
  android:visibility="visible" />
</FrameLayout>


버튼을 눌렀을 때 중첩된 뷰 바꾸기

프레임 레이아웃 안에 들어가 있는 두 개의 뷰 중에서 처음에는 두 번째 뷰가 보였지만 버튼을 눌렀을 때 첫 번째 뷰가 보이도록 만들 수도 있습니다.

물론 버튼을 누를 때마다 첫 번째 뷰와 두 번째 뷰가 번갈아 보이도록 만들 수도 있죠.

사용자가 버튼을 클릭했을 때 무언가가 동작하도록 만드는 과정이 아직 익숙하지 않을 수도 있습니다.

하지만 하나씩 진행해보면 그리 복잡하지 않습니다.

화면에 버튼을 하나 추가하고 onClick 속성의 값으로 자바 소스 코드에 들어갈 메소드의 이름을 지정합니다.

그리고 그 메소드를 소스 코드에 추가합니다.

만약 버튼 클릭 시 onButton1Clicked라는 메소드가 동작하도록 지정하고 onButton1Clicked 메소드에서 changeImage라는 메소드를 호출하도록 입력했다면 다음과 같이 코드를 입력할 수 있습니다.

private void changeImage() {
  if (imageIndex == 0) {
    imageView.setVisibility(View.VISIBLE);
    imageView2.setVisibility(View.INVISIBLE);

    imageIndex = 1;
  } else if (imageIndex == 1) {
    imageView.setVisibility(View.INVISIBLE);
    imageView2.setVisibility(View.VISIBLE);

    imageIndex = 0;
  }
}

이 소스 코드에서는 상태에 따라 두 개의 이미지가 보이거나 보이지 않도록 설정합니다. 소스 코드에서 imageView, imageView2, imageIndex 변수는 미리 선언되고 초기화되어 있어야 합니다.

사용자가 버튼이나 화면을 눌렀을 때 발생하는 이벤트에 대해서는 나중에 자세히 살펴볼 것입니다.

 

 


생각해보기

뷰를 중첩시키고 보였다 안보였다 하는 또 다른 예는 어떤 것이 있을까요?
- 버튼색이 바뀌는것도 색을입히는것말고 이미 색이 입혀진 버튼을 보였다 안보였다 할수 있을것 같다.

화면의 일부분이 바뀌면서 보이는 것 말고 전체 화면이 다른 화면으로 바뀌면서 보이도록 만들 수도 있을까요?
- 가장 밖의 레이아웃을 프레임레이아웃으로 설정하다면 가능할것 같다.

이렇게 하기 위해서는 새로운 화면을 또 추가해야 하는 걸까요?
- 여러개의 화면을 숨겨놓고 사용하는것이기 때문에 따로 필요하지 않을것 같다.


출처 : http://www.edwith.org/boostcourse-android/lecture/17043/


상대 레이아웃

상대 레이아웃은 뷰를 담고 있는 부모 레이아웃이나 그 안에 들어있는 다른 뷰들과의 상대적 위치를 이용해 화면을 배치하는 레이아웃입니다. 

상대 레이아웃 사용 방식
예를 들어, 화면의 아래쪽에 버튼을 붙이고 싶다면 layout_alignParentBottom 속성의 값을 true로 설정하는 것만으로 충분합니다.
리니어 레이아웃의 경우에는 위에서부터 차례대로 쌓아야 가장 아래쪽까지 배치할 수 있지만 상대 레이아웃은 위에 아무것도 없어도 화면의 가장 아래쪽에 뷰를 붙여둘 수 있습니다.

상대 레이아웃을 이용한 뷰의 배치

상대 레이아웃이 뷰를 담고 있다면 이 뷰의 입장에서는 상대 레이아웃이 부모 레이아웃이 됩니다.

그리고 부모 레이아웃의 상대적 위치를 이용할 수 있습니다.

 

상대 레이아웃을 이용한 뷰의 배치 방법
A라는 이름의 뷰는 부모 레이아웃의 위쪽에 붙이고 B라는 뷰는 A 뷰의 아래쪽에 붙일 수 있습니다.
같은 상대 레이아웃 안에 들어있는 다른 뷰와의 상대적 위치를 이용하는 것이죠.

부모 레이아웃과의 상대적 위치를 지정할 때 사용하는 속성으로는 layout_alignParentTop, layout_alignParentBottom, layout_alignParentLeft, layout_alignParentRight 등이 있습니다.

부모 레이아웃의 가운데에 배치하기 위한 layout_centerInParent 속성도 있죠.

다른 뷰와의 상대적 위치를 지정할 때 사용하는 속성으로는 layout_toLeftOf, layout_toRightOf, layout_alignTop, layout_alignBottom 등이 있습니다.

부모 레이아웃과의 상대적 위치를 지정할 때 사용하는 속성들은 모두 Parent 라는 단어가 들어가 있지만 다른 뷰와의 상대적 위치를 지정할 때 사용하는 속성들에는 Parent 라는 단어가 들어가 있지 않습니다.

 

위, 아래 뷰를 두고 가운데 꽉 차게 배치하기

리니어 레이아웃을 이용해 화면을 배치할 때 쉽게 되지 않는 것 중의 하나가 위, 아래에 뷰를 두고 가운데에 또 다른 뷰를 두면서 꽉 차게 만드는 것입니다.

가운데에 있는 뷰를 꽉 차게 하려면 layout_height 속성의 값을 match_parent로 해야 하는데 이렇게 하면 리니어 레이아웃에서는 아래쪽 뷰가 보이지 않는 문제가 생깁니다.

위, 아래 버튼을 두고 가운데 버튼이 꽉 차게 만든 화면
상대 레이아웃을 사용하면 위쪽에 있는 뷰에는 layout_alignParentTop 속성, 아래쪽에 있는 뷰에는 layout_alignParentBottom 속성을 지정합니다.
그리고 가운데 있는 뷰의 layout_height 속성에 match_parent 값을 지정하면 위, 아래 뷰와 상관없이 화면이 꽉 차게 됩니다.
이 상태에서 layout_above와 layout_below 속성을 추가로 지정하면 위, 아래 뷰가 차지하고 있는 영역을 제외한 가운데 영역을 꽉 차게 만들 수 있습니다.

상대 레이아웃 안에 들어있는 뷰들에는 아래와 같이 속성이 지정될 수 있습니다.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >

<Button
  android:id="@+id/button1"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="Button"
  android:layout_alignParentTop="true" />

<Button
  android:id="@+id/button2"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="Button"
  android:layout_alignParentBottom="true" />

<Button
  android:id="@+id/button3"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_below="@+id/button1"
  android:layout_above="@+id/button2"
  android:text="Button" />

</RelativeLayout>




생각해보기

  1. 상대 레이아웃을 잘 사용할 수 있다면 다른 레이아웃은 필요 없는 걸까요?
    -필요로 안할수도 있겠지만 역시 개발의 중요함은 편리함. 상대레이아웃 여러개쓰는것보다 그걸 위해 만들어진 다른 레이아웃을 쓰는게 더 효과적일수있다.
  2. 리니어 레이아웃과 상대 레이아웃을 잘 조합해서 사용하는 방법을 생각해보세요.
    - 전체적인건 상대레이아웃으로 잡고 그안에 리니어들을 넣어서 깔끔하게 정리할 수 있다.
  3. 화면에 보이는 뷰들의 일부가 겹쳐있도록 만들 수도 있을까요?
    - 가능하지만 지저분해보일수있으므로 정리가 필요하고 우선순위도 필요할것 같다.


출처 : http://www.edwith.org/boostcourse-android/lecture/17042/


리니어 레이아웃(LinearLayout)의 방향 속성과 정렬 속성

리니어 레이아웃에서 가장 중요한 속성은 방향을 결정하는 orientation 속성입니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" 
  android:layout_width="match_parent"
  android:layout_height="match_parent"
>

뷰를 정렬할 때는 layout_gravity와 gravity 속성이 사용됩니다.

Gravity는 지구의 ‘중력’처럼 끌어당기는 힘을 의미한다고 생각하면 이해하기 쉽습니다.

가로 방향으로 보았을 때 layout_gravity 속성의 값이 left이면 뷰를 왼쪽으로 끌어당겨 정렬하라는 의미거든요.

정렬은 가로 방향으로 왼쪽, 가운데, 오른쪽이 있을 수 있고 세로 방향으로 위쪽, 가운데, 아래쪽이 있을 수 있습니다.

이 외에도 여러 가지 속성이 있죠.

주의할 점은 layout_gravity는 뷰를 정렬하는 데 사용되고 gravity는 뷰 안에 들어있는 내용물을 정렬할 때 사용된다는 점입니다.

버튼을 예로 들면 버튼 안에 들어있는 글자가 내용물이 되니 gravity 속성을 주면 그 글자를 정렬하겠다는 의미가 됩니다.

또 한가지 주의할 점은 여유 공간이 있어야 정렬할 수 있다는 점입니다.

예를 들어 버튼의 가로 크기 속성인 layout_width의 값을 wrap_content로 해놓으면 gravity 속성의 값으로 가로 방향 왼쪽이나 오른쪽으로 정렬하라는 값을 주더라도 정렬은 아무 의미가 없습니다.

움직일 공간이 없기 때문이죠.


뷰의 마진, 패딩 그리고 공간분할

리니어 레이아웃 안에 들어가 있는 뷰가 차지하는 공간은 기본적으로 가로/세로 크기를 지정하는 layout_width와 layout_height 속성에 의해 결정됩니다.

그리고 추가적으로 마진을 설정할 수 있습니다.

마진(Margin)은 뷰의 테두리선 바깥쪽 공간을 얼마나 띄울 것인지를 지정하는 속성입니다.

예를 들어, layout_margin 속성의 값을 10dp 로 주면 위, 아래, 좌, 우 공간을 10dp 만큼 띄워줍니다.

원한다면 한쪽만 마진을 줄 수도 있습니다.

패딩(Padding)은 뷰 안에 들어있는 내용물을 테두리 선과 얼마나 띄울 것인지를 지정하는 속성입니다.

버튼 안에 들어있는 글자가 테두리선과 너무 붙어있다는 느낌이 든다면 이 속성을 사용해 공간을 띄워줄 수 있습니다.

예를 들어, padding 속성의 값을 10dp 로 주면 위, 아래, 좌, 우 공간을 10dp 만큼 띄워줍니다.

원한다면 한쪽만 패딩을 줄 수도 있습니다.

뷰의 영역 구분

처음 안드로이드 화면을 만들어볼 때 가장 많이 혼동하는 속성이 layout_weight 입니다.

이 속성은 공간분할에 많이 사용됩니다.

예를 들어, 두 개의 버튼을 가로 방향으로 똑같은 크기만큼 반반씩 공간을 차지하도록 만들고 싶을 때 사용합니다.

그런데 이 속성은 남아있는 여유 공간만 분할합니다.

이 때문에 두 개의 버튼을 가로 방향으로 추가했다면 layout_width 속성의 값은 0dp 로 주는 것이 필요합니다.

layout_width 속성의 값이 0dp 이고 layout_weight 속성이 각각 1이라면 이 두 개의 버튼은 공간을 반반씩 나누어 가집니다.

왼쪽 버튼이 2/3, 오른쪽 버튼이 1/3씩 공간을 차지하도록 하고 싶다면 layout_width 속성의 값이 0dp 이고 layout_weight 속성이 각각 2와 1이 되도록 만들면 됩니다.

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
  android:layout_width="0dp"
  android:layout_height="wrap_content"
android:layout_weight="1"
android:text="확인" /> 
<Button
      android:layout_width="0dp"
      android:layout_height="wrap_content"
android:layout_weight="1"
android:text="취소" /> 
</LinearLayout>


 


생각해보기

  1. 리니어 레이아웃 안에 리니어 레이아웃을 포함시키면 어떤 화면이든 다 만들 수 있는 걸까요?
    -그렇다. 하지만 복잡한 레이아웃을 쉽게표현할수있는 다른 레이아웃들이 많다.
  2. 화면의 위, 아래 끝에 작은 뷰를 배치하고 싶다면 리니어 레이아웃을 쓰는 것보다 더 좋은 방법이 있을까요?
    -제약레이아웃을 쓴다.


출처:http://www.edwith.org/boostcourse-android/lecture/17041/


대표적인 레이아웃

제약 레이아웃 외에 대표적인 레이아웃으로 리니어 레이아웃(LinearLayout), 상대 레이아웃(RelativeLayout), 프레임 레이아웃(FrameLayout) 등을 들 수 있습니다.

그중에서도 리니어 레이아웃이 가장 간단하면서도 자주 사용됩니다.

리니어 레이아웃은 상자를 쌓듯이 뷰를 하나씩 쌓을 수 있는 레이아웃입니다.

화면에서 뷰가 차지하는 영역을 상자라고 보고 이 상자를 한쪽 방향으로 쌓을 수 있게 해 줍니다.

상자를 위로도 쌓을 수 있고, 바닥에 어느 한방향의 일렬로 놓을 수도 있다고 생각하면 쉽습니다.

화면에서는 뷰를 아래쪽으로 쌓거나 오른쪽으로 쌓을 수 있도록 해주는데 어느 방향으로 쌓을 것인지를 먼저 결정해야 합니다.

방향 속성인 orientation 속성을 이용해 가로 방향은 Horizontal, 세로 방향은 Vertical로 지정합니다.

그다음에는 단순히 쌓기만 하면 됩니다.

아주 쉬운 레이아웃이지만 리니어 레이아웃 안에 다시 리니어 레이아웃을 여러 개 집어넣고 안에 들어간 리니어 레이아웃 각각에 서로 다른 orientation 속성을 설정하여 아주 복잡한 화면도 만들 수 있습니다.

리니어 레이아웃 사용 방식

생각해보기

  1. 리니어 레이아웃 안에 리니어 레이아웃을 포함시키면 어떤 화면이든 다 만들 수 있는 걸까요?
    -가능하다. 하지만 리니어레이아웃 여러개쓸것을 쉽게 다른 레이아웃으로 표현할수 있다.


출처: http://www.edwith.org/boostcourse-android/lecture/17040/


제약 레이아웃 (ConstraintLayout)

제약 레이아웃은 프로젝트를 처음 만들었을 때 자동으로 만들어지는 레이아웃입니다.

자동으로 만들어진 XML 레이아웃 파일인 activity_main.xml 파일을 열어보면 가장 바깥에 있는 최상위 태그가 ConstraintLayout인 것을 확인할 수 있습니다.

이 최상위 태그는 화면 전체를 담고 있는 레이아웃을 의미합니다.

그 태그 안에 들어있는 속성 중에 xmlns라는 지시자가 들어 있습니다.

이 지시자는 XML 파일 하나당 한 번씩만 사용되면 되는데, 보통 최상위 태그에 들어 있습니다.

xmlns 지시자에는 상당히 긴 URL이 값으로 설정됩니다.

이것은 안드로이드 SDK에 들어있는 속성을 사용하겠다는 의미로 해석되는데 일단 같은 URL이 매번 자동으로 만들어지므로 크게 신경 쓰지 않아도 됩니다.

다만 안드로이드 SDK에 들어있는 속성은 android: 라는 접두어를 붙여서 사용하므로 각각의 속성에 대부분 android: 접두어가 붙게 된다고 이해하면 됩니다.

이와 다르게 app라는 속성이 사용되는 경우도 있는데 이것은 여러분이 만든 프로젝트에서 지정한 속성을 사용하겠다는 의미입니다.

예를 들어, 외부 라이브러리를 사용하는 경우에는 안드로이드 SDK에 들어있지 않은 별도의 속성을 사용할 수 있게 되는데 이때는 app라는 지시자를 추가하고 각 속성의 앞에 app: 라는 접두어를 붙이면 됩니다.

제약 레이아웃은 제약조건을 이용해 그 안에 추가된 뷰들의 위치를 결정합니다.

그리고 그 제약조건은 연결선을 통해 만들어지죠.

연결선은 뷰의 상, 하, 좌, 우에 있는 연결점을 다른 레이아웃이나 위젯의 상, 하, 좌, 우와 연결하여 만들 수 있습니다.

만약 버튼을 제약 레이아웃 안에 추가했다면 버튼을 담고 있는 부모 레이아웃인 제약 레이아웃과의 연결선을 만들 수도 있고 그 안에 들어있는 다른 뷰들과의 연결선을 만들 수도 있습니다.

제약조건

주의할 점은 연결선은 그 뷰의 위치를 결정할 만큼 만들어져야 한다는 것입니다.

예를 들어, 버튼의 연결선을 버튼의 왼쪽 연결점과 부모 레이아웃의 왼쪽 면과 연결하도록 하나만 만들었다면 이 버튼의 위치는 결정할 수 없게 됩니다.

왜냐하면, 이 상태에서는 버튼이 위, 아래 공간 중에서 어디에 위치하도록 할 것인지 알 수 없기 때문입니다.

따라서 버튼의 위쪽에 연결선을 하나 더 만들어주는 것이 필요합니다.

만약 상, 하 연결선을 모두 부모 레이아웃과 연결하여 만들게 되면 그 뷰는 부모 레이아웃의 가운데 지점에 있게 됩니다.

상, 하로 이어진 선의 중간 지점이죠.

상, 하, 좌, 우 모두 부모 레이아웃과 연결하면 어떻게 될까요?

화면의 가운데 부분에 위치하게 됩니다.

 

 


생각해보기

  1. 레이아웃 안에 레이아웃을 넣는 방식으로 3~4개의 레이아웃을 중첩시켜 넣은 후 그 안에 버튼을 넣으면 하나의 
    레이아웃 안에 버튼을 넣었을 때와 다른 점이 있을까요? 어떤 경우에 이렇게 만들까요?
    -하나의 레이아웃에 넣었을때 만약 수정이 필요할때 일일히 하기가 힘들수있는데 레이아웃자체가 이것을 그룹화해주는 역할을 하는것 같다.
  2. 제약 레이아웃 안에 두 개의 버튼을 넣고 하나의 버튼을 다른 버튼과 연결하여 위치시키면 
    하나의 버튼을 움직였을 때 다른 버튼도 따라 움직일까요?
    -연결하였을때 연결당한버튼을 움직이면 원래것도 같이 이동하지만 원래것을 이동하였을때는 같이 움직이지않는다.


출처: http://www.edwith.org/boostcourse-android/lecture/17039/



뷰 (View)

뷰는 안드로이드 기본 화면을 구성하는 모든 기본 화면 구성요소를 말합니다.

눈에 보이지 않는 것도 있긴 하지만 눈에 보이는 각각의 것들을 뷰라고 이해하면 쉽습니다.

뷰 중에 눈에 보이지 않는 것들이 있다 보니 눈에 보이는 것들은 위젯, 눈에 보이지 않는 것들은 레이아웃이라고 구분합니다.

레이아웃은 그 안에 다른 뷰들을 담아둘 수 있는데 레이아웃도 뷰를 상속하여 정의되었기 때문에 레이아웃 안에 레이아웃도 담을 수 있습니다.

레이아웃 안에 레이아웃, 다시 그 레이아웃 안에 레이아웃을 넣는 방식을 사용하면 아주 복잡한 화면이 만들어지겠죠?

다른 뷰들을 담아둘 수 있도록 뷰그룹을 정의해두었는데 레이아웃은 이 뷰 그룹을 상속합니다.

아래 계층도를 보면 좀 더 쉽게 이해가 될 겁니다.

뷰의 크기 속성

화면에 추가한 버튼은 눈에 바로 보이는 것이고 그 버튼을 담고 있는 눈에 보이지 않는 것이 레이아웃입니다.

프로젝트를 처음에 만들면 제약 레이아웃이라는 것이 버튼을 담고 있는 형태로 만들어집니다.

버튼과 제약 레이아웃은 뷰의 한 종류 입니다. 뷰는 화면의 일정 공간을 차지하므로 크기 속성이 필수입니다.

즉, 크기를 알아야 화면의 공간 중에서 얼마만큼을 뷰에게 할당해줄지 알 수 있습니다.

화면을 구성할 때는 XML 파일을 만들게 되는데 XML 파일 안에는 태그와 속성들이 들어가게 됩니다.

이 XML 파일을 시스템이 읽어 들여 앱의 화면으로 보여주게 됩니다.

태그가 추가된 레이아웃의 구성

이 각각의 태그는 뷰를 의미하는데 가로, 세로의 크기가 필수 속성이므로 layout_width, layout_height 속성을 반드시 넣어주어야 합니다.

속성 앞에 붙어있는 android: 라는 지시어는 안드로이드 SDK에서 정의한 속성이라는 의미로 대부분의 속성이 SDK의 속성이므로 보통은 눈여겨보지 않아도 됩니다.

android:layout_width 속성을 layout_width 속성이라고 부르는 이유죠.

크기를 지정하는 방법은 세 가지가 있습니다.

"match_parent"는 상위 뷰의 크기에 맞게 구성 요소를 확장하고, 뷰 안에 들어있는 내용물의 크기에 딱 맞게 크기를 결정하는 wrap_content를 사용할 수도 있고 원하는 크기를 숫자로 지정할 수도 있습니다.

이때 크기를 나타내는 숫자 뒤에는 px나 dp와 같은 단위를 붙여줍니다.




생각해보기

  1. 버튼에는 얼마나 많은 속성이 들어 있을까요?
    -기본적인 높이 너비 안에들어갈 글씨 말고도 밑에 모든속성보기를 누르면 그 속성의 갯수가 많다는걸 알수있다.
  2. 버튼이 텍스트뷰를 상속받아 만들어진 것이라면 버튼을 텍스트뷰라고 말할 수 있는 걸까요?
    -이건 좀 애매한데 나는없다고본다. 애초에 버튼이 텍스트뷰를 상속받아서 만들어진것이라 속성들을 똑같이 가지고있지만 단지 상속되어있다는 것으로 버튼을 텍스트뷰라고하기는 애매한것 같다.


+ Recent posts