일반적인 프로그래밍 언어에서 화면에 컨트롤을 배치할 때 제공하는 정렬 기능을 안드로이드에서도 그대로 사용할 수 있습니다. 이 때 사용하는 용어가 안드로이드에서는 조금 다른 것을 볼 수 있는데 일반적인 정렬(align)은 순서대로 놓여 지다는 의미로 이해할 수 있으며, 안드로이드에서 사용하는 배치(gravity)는 어느 쪽에 무게 중심을 놓은 것인가의 의미로 이해할 수 있습니다. 하지만 똑같이 생각해도 상관없습니다. 레이아웃에서 정렬 기능이 필요한 경우는 다음과 같이 두 가지로 나눌 수 있습니다.



정렬 속성 

설명 

 layout_gravity

부모 컨테이너의 여유 공간에 뷰가 모두 채워지지 않아 여유 공간 안에서 뷰를 정렬할 때 

 gravity

뷰에서 화면에 표시하는 내용물을 정렬할 때(텍스트뷰의 경우, 내용물은 글자가 되고 이미지뷰의 경우 내용물은 이미지가 됨) 


먼저 부모 컨테이너의 여유 공간에 뷰가 모두 채워지지 않을 경우에 사용하는 layout_gravity는 뷰의 layout_width 나 layout_height 속성을 wrap_content로 할 경우에 같이 사용할 수 있습니다. 예를 들어, 세로 방향으로 설정된 리니어 레이아웃에 추가된 버튼들의 layout_width 속성을 wrap_content로 하게 되면 각각의 버튼들은 한 줄에 한 개씩 추가되면서 글자가 보이는 만큼의 크기로만 보이므로 나머지 가로 공간은 여유 공간으로 남게 됩니다. 안드로이드는 이렇게 여유 공간이 있을 경우 디폴트로 왼쪽 정렬을 하게되는데 layout_gravity 속성을 직접 설정하게 되면 중앙 또는 오른쪽 정렬을 할 수 있습니다.


예제를 보도록 하겠습니다.



gravity.xml 

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

    xmlns:tools="http://schemas.android.com/tools"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity" >


    <Button

        android:id="@+id/button01"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="left"

        android:text="버튼1" />

    

    <Button

        android:id="@+id/button02"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="center"

        android:text="버튼2" />

    

    <Button

        android:id="@+id/button03"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="right"

        android:text="버튼3" />


</LinearLayout>



실행을 해보면 결과는 다음과 같습니다.





뷰에 보이는 내용물을 정렬하는 경우에는 gravity 속성을 사용합니다. gravity 속성은 뷰가 화면에서 차지하는 영역이 충분히 큰 경우에 생기는 여유 공간 안에서 어떻게 정렬할 것인지를 결정합니다. gravity가 적용될 수 있는 대표적인 내용물로는 텍스트뷰 안에 표시되는 텍스트나 이미지뷰에 표시되는 이미지를 들 수 있습니다. gravity 속성에 넣을 수 있는 값들은 layout_gravity와 같으며, 필요한 경우에는 '|' 연산자를 이용해 여러 개의 값을 같이 설정할 수도 있습니다. 이 때 주의할 점은 '|' 연산자 양쪽에 공백이 없어야 한다는 점입니다.


다음은 하나의 텍스트뷰를 화면 전체에 채운 후 그 안에 표시되는 텍스트를 왼쪽 상단, 중앙, 그리고 오른쪽 하단에 표시할 경우에 사용되는 XML 레이아웃으로 각각 'left|top', 'center', 'right|bottom' 값이 설정되었습니다. 예제를 보도록 하겠습니다.



<TextView

        android:id="@+id/button01"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="left|top"

        android:text="left|top" /> 

 




 <TextView

        android:id="@+id/button02"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="center_horizontal|center_vertical"

        android:text="center" />

 





<TextView

        android:id="@+id/button03"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="right|bottom"

        android:text="right|bottom" /> 

 



gravity 속성으로 지정할 수 있는 값으로는 위와 같이 대표적인 경우 이외에도 여러 가지가 있으며 각각의 값에 대한 설명은 다음과 같습니다.


정렬 속성값 

설 명 

 top

 대상 객체를 위쪽 끝에 배치하기 

 bottom

대상 객체를 아래쪽 끝에 배치하기하기 

 left

대상 객체를 왼쪽 끝에 배치하기 

 right

대상 객체를 오른쪽 끝에 배치하기 

 center_vertical

대상 객체를 수직 방향의 중앙에 배치하기 

 center_horizontal

대상 객체를 수평 방향의 중앙에 배치하기 

 fill_vertical

대상 객체를 수직 방향으로 여유 공간만큼 확대하여 채우기 

 fill_horizontal

대상 객체를 수평 방향으로 여유 공간만큼 확대하여 채우기 

 center

대상 객체를 수직 방향과 수평 방향의 중앙아 배치하기 

 fill

대상 객체를 수직 방향과 수평 방향으로 여유 공간만큼 확대하여 채우기 

 clip_vertical

-대상 객체의 상하 길이가 여유 공간보다 클 경우에 남는 부분을 잘라내기

-top|clip_vertical 로 설정한 경우 아래쪽에 남는 부분 잘라내기

-bottom|clip_vertical 로 설정한 경우 위쪽에 남는 부분 잘라내기

-center_vertical|clip_vertical로 설정한 경우 위쪽과 아래쪽에 남는 부분 잘라내기 

 clip_horizontal

-대상 객체의 좌우 길이가 여유 공간보다 클 경우에 남는 부분을 잘라내기

-right|clip_horizontal 로 설정한 경우 왼쪽에 남는 부분 잘라내기

-left|clip_horizontal 로 설정한 경우 오른쪽에 남는 부분 잘라내기

-center_horizontal|clip_horizontal로 설정한 경우 왼쪽과 오른쪽에 남는 부분 잘라내기 


이것으로 gravity, layout_gravity 설명을 마치도록 하겠습니다.


도움이 되셨다면 손가락 한번 꾸~욱 눌러주시면 감사하겠습니다.^^


Posted by 정윤문경아빠

앞전에는 리니어 레이아웃과 그 안에 들어 있는 세 개 버튼은 XML로 정의한 후 이 XML 리소스 파일의 위치를 액티비티에서 사용된 setContentView() 메소드의 파라미터로 전달하여 화면에 보여주었습니다. 이렇게 화면에 보이는 레이아웃을 XML로 정의하게 되면 나중에 화면 구성을 바꿀 때도 간단하게 XML만 수정하면 되므로 훨씬 이해하기 쉽고 모듈화된 구성이라고 할 수 있습니다. 그러나 종종 코드 상에서 화면을 구성해야 하는 경우가 생기게 됩니다. 예를 들어 사용자가 입력한 데이터, 파일에서 읽어 들인 데이터 또는 네트워킹을 통해 서버에서 받아온 데이터의 유형에 따라 화면의 구성을 바꾸고 싶다면 XML로 정의하는 것보다 자바 코드에서 화면을 구성하는 것이 훨씬더 효율적인 방법입니다. 예제를 보도록 하겠습니다.



MainActivity.java 

package com.example.example;


import android.app.Activity;

import android.os.Bundle;

import android.widget.Button;

import android.widget.LinearLayout;


public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

                // new 연산자로 리니어 레이아웃 만들고 방향 설정

LinearLayout mainLayout = new LinearLayout(this);   

mainLayout.setOrientation(LinearLayout.VERTICAL);

                 // new 연산자로 레이아웃 안에 추가될 뷰들의 파라미터 생성

LinearLayout.LayoutParams params = 

new LinearLayout.LayoutParams( 

LinearLayout.LayoutParams.MATCH_PARENT, 

LinearLayout.LayoutParams.WRAP_CONTENT);

                // 버튼에 파라미터 설정하고 레이아웃에 추가

Button button01 = new Button(this);

button01.setText("버튼1");

button01.setLayoutParams(params);

mainLayout.addView(button01);

                // 새로 만든 레이아웃을 화면에 설정

setContentView(mainLayout);

}


}



위 코드를 실행을 시키면 다음과 같은 결과가 나오게 됩니다.




프로젝트를 처음 만들었을 때 볼 수 있었던 자바 코드에는 onCreate() 메소드 안에 setContentView() 메소드가 사용되었는데, 그것과 앞에서 살펴본 코드의 다른 점은 setContentView() 메소드 안에 들어가는 파라미터가 R.layout.main과 같이 XML 레이아웃으로 정의된 리소스가 아니라 자바 코드에서 만든 뷰그룹 객체라는 것입니다. 리니어 레이아웃으로 만든 객체를 setContentView() 메소드의 파라미터로 전달하면 리니어 레이아웃 안에 추가된 뷰들을 배치한 화면을 볼 수 있습니다. 안드로이드는 XML 레이아웃에서 정의할 수 있는 대부분의 속성들을 자바 코드에서 객체를 만들거나 객체의 메소드를 호출하여 설정할 수 있도록 지원하는데 리니어 레이아웃의 방향 속성도 마찬가지입니다. new LinearLayout()을 통해 만들어진 리니어 레이아웃 객체에는 setOrientation() 메소드를 사용할 수 있으며, setOrientation(LinearLayout, VERTICAL)과 같이 방향 속성을 정의한 상수를 파라미터로 전달하면 세로 방향 또는 가로 방향으로 뷰를 추가할 수 있습니다. 뷰 객체를 코드에서 만들 때 뷰의 생성자에는 항상 Context 객체가 전달되어야 하는데 액티비티는 컨텍스트(Context)를 상속하므로 액티비티 클래스 안에서는 this를 Context 객체로 사용할 수 있습니다.

자바 코드 상에서 뷰를 만들어 뷰그룹에 추가할 때는 뷰의 배치를 위한 속성을 설정할 수 있는 LayoutParams 객체를 사용합니다. LayoutParams 객체를 새로 만들 경우에는 반드시 뷰가 추가될 영역에 대한 기본 채우기(fill) 속성을 지정해야 하며, 이 때 사용하는 두 가지 상수인 LayoutParams.MATCH_PARENT 와 LayoutParams.WRAP_CONTENT 중 하나가 사용됩니다. 필요한 경우에는 이 두 가지 상수가 아닌 가로와 세로의 크기값을 직접 설정할 수도 있습니다.

뷰그룹에 뷰를 추가하기 위해서는 addView() 메소드를 사용합니다. addView() 메소드에는 추가할 뷰를 파라미터로 전달할 수 있으며, 필요한 경우 부모 컨테이너에서 사용할 레이아웃 파라미터인 LayoutParams 객체를 같이 전달할 수도 있습니다. 앞서 살펴보았던 코드에서는 addView() 메소드를 호출할 때 LayoutParams 객체를 전달하지 않고 버튼 객체의 setLayoutParams() 메소드를 이용해 레이아웃 파라미터를 먼저 설정한 후 addView() 메소드에는 버튼 객체만을 전달하는 방법을 사용했습니다.


다음 포스팅에서는 정렬 방향 설정하는 속성인 gravity에 대해서 알아보도록 하겠습니다.



Posted by 정윤문경아빠

이번에는 리니어 레이아웃에 대해서 알아보겠습니다. 리니어 레이아웃을 보통 가장 많이 사용하며 이 레이아웃으로만으로도 웬만한 앱은 만들 수 있습니다. 리니어 레이아웃에서 빠질 수 없는게 방향 설정하기 입니다. 방향 설정은 리니어 레이아웃에서 꼭 필요한 속성으로, 뷰를 차례대로 추가할 때 가로 방향으로 할 것인지 또는 세로 방향으로 할 것인지를 지정할 수 있습니다. 리니어 레이아웃을 처음 추가했을 때는 기본 값이 세로방향으로 되어 있습니다. 리니어 레이아웃 안에 세 개의 버튼을 순서대로 추가할 경우에 XMl과 자바 코드를 구성하는 방법은 다음과 같습니다.



LinearLayout_vertical.xml 

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

    xmlns:tools="http://schemas.android.com/tools"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity" >


    <Button

        android:id="@+id/button01"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="버튼1" />

    

    <Button

        android:id="@+id/button02"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="버튼2" />

    

    <Button

        android:id="@+id/button03"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="버튼3" />


</LinearLayout>



위 속성에 보면 android:orientation="vertical" 보이시나요? vertical 은 수직방향으로 레이아웃을 구성하겠다는 의미입니다.


프로젝트를 실행하면 다음의 그림과 같이 나오게 됩니다.





버튼이 세로(수직) 방향으로 내려오네요. 그렇다면 가로 방향은 어떻게 하면 될까요? 단순히 리니어 레이아웃의 orientation 속성 값만 'horizontal'로 바꾸면 됩니다. 속성을 바꾼 후에 실행해 보면 다음과 같은 화면을 볼 수 있습니다.





그런데 에뮬레이터에 보이는 화면을 보면 세 개의 버튼 중에 첫번째 버튼만 보이는 것을 알 수 있습니다. 왜 그럴까요? 그 이유는 버튼들 가로 속성을 match_parent를 했기 때문입니다. 그러므로 리니어 레이아웃을 세로 방향으로 했을때는 정상적으로 보이지만 가로방향을 했을때에는 버튼 2, 3이 버튼1에 가려지게 되는것입니다. 이걸 정상적으로 볼려면 버튼들 속성을 바꿔주면 됩니다. 버튼들의 각각 속성인 android:layout_width="match_parent" 를 android:layout_width="wrap_content"로 바꿔 보겠습니다.



네...이제 화면이 정확하게 나오네요.


다음 포스팅에서는 리니어 레이아웃을 자바코드로 만드는 방법을 알아보도록 하겠습니다.


Posted by 정윤문경아빠