JAVA 코드에서 Activity를 상속받은 클래스는 화면을 구성하기위해서 기본적으로 main.xml이라는 기본으로 생성되는 레이아웃을 생성하여 보여주기위해 setContentView()를 사용한다. (activity 클래스에서 onCreate()는 자바SE의 main() 처럼 프로그램 실행시 가장 먼저 실행되는 메서드이다.) 
package com.example.TestAndroid;

import android.app.Activity;
import android.os.Bundle;

public class TestAndroid extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
 xml문서의 레이아웃은 뷰를 담는 컨테이너 역할을 하는 부분으로 그 내부에 실제 화면에 나타날 View 객체들의 목록과 구조, 속성들이 정의되어있다. 이러한 xml문서를 실제 안드로이드 프로그램이 실행될 때 메모리에 올리는 과정은 ADT에 포함된 aapt(Android Asset Packaging Tool)에 의해 수행된다. 바로 이러한 수행을 하도록 코드상에 존재하는  메소드가 setContentView() 인 것이다. 이러한 동작을 Inflation(전개)이라고 한다. 

 그럼 여기서 자바 코드로 xml문서에 접근이 가능하기 때문에 xml문서 없이 레이아웃을 만들 수 있을 것이다.  
package com.example.InflationTest;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;

public class InflationTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout linear = new LinearLayout(this);
        linear.setOrientation(LinearLayout.VERTICAL);
        linear.setBackgroundColor(Color.WHITE);
        
        TextView text = new TextView(this);
        text.setText("코드로 생성");
        text.setGravity(Gravity.CENTER);
        text.setTextColor(Color.RED);
        text.setTextSize(20);
        
        linear.addView(text); //부모 자식관계 설정과정
        setContentView(linear);
    }
}
 코드상에서 생성한 LinearLayout을 setContentVIew()에 넘겨주었다. 출력결과는 역시 xml로 만든 레이아웃과 다를게 없다.


조금 더 파고 들어 가 보면, 안드로이드는 xml문서의 전개를 위해 시스템 수준에서 전개자를 따로 제공하는데 Activity의 getSystemService()로 전개자를 구할 수 있다. 그리고 전개자 객체의 inflate()로 전개를 수행한다. 
 - Vew inflate(int resource, ViewGroup root)
 inflate()는 또 View의 정적 매소드로도 존재하는데 다음의 사용법과도 동일하다.
 - static View inflate(Context context, int resource, ViewGroup root)

 그럼 여기서 또 헷갈려진다. xml을 전개하여 액티비티에 전개하는 과정은 맨 처음 setContentVIew(linear)로 실행하였는데 위의 inflate()메소드는 또 뭐란말인가.. 
 사실 onCreate() 내부에서 아래 두 코드 모두 동일한 결과를 가져온다.
 - setContentView(R.layout.main)
 - LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

   View v = (View) inflater.inflate(R.layout.main, null);    setContentView(v);  즉, 결과는 같지만 inflate()를 사용하는 것은 xml문서를 JAVA코드 단계에서 시스템적으로 언제든지 전개 할 수 있다는 것을의미한다. 

 자바에 익숙해 져 있다 안드로이드 덕분에 XML을 알게되었는데, 처음엔 별 생각없이 그저 나눠서 디자인 하니까 편하다고만 생각했는데 자세히 알아가면 갈 수록 단순한 개념이 아니라는걸 느낀다.


 

'Programming > ANDROID' 카테고리의 다른 글

INSTALL_FAILED_INSUFFICIENT_STORAGE  (2) 2011.04.11
eclipse (Helios)에서 android 개발 코딩 속도 버그 수정  (2) 2011.04.06
Layout 중첩 - Multi Page  (6) 2011.03.29
ViewGroup - RelativeLayout  (2) 2011.03.29
ViewGroup - TableLayout  (1) 2011.03.29
 레이아웃 중첩이란 말 그대로 레이아웃 안에 레이아웃을 넣는 방법을 말한다. 앞서 말했듯이 꼭 써야하는 경우에는 써야하지만 최대한 레이아웃은 최소화 하는것이 프로그램 퍼포먼스 상승에 도움이 된다는 것을 잊지말자.

 이제까지 배운 레이아웃들을 한데 모아 버튼을 누를때마다 페이지가바뀌는 프로그램을 만들어보자. 물론 진정한 의미로의 새로운 창을 메모리에 올리는 개념이 아니라(이 부분은 나중에 ACTIVITY 클래스에대해 자세히 배우게 될것이다.) 모든 레이아웃을 처음에 메모리에 올리지만 하나의 레이아웃만 Visibility를 "visible"로 고 나머지는 "invisible"로 설정하여 화면에만 안나타나게 하는 것이다. 이를 위해서 앞에서 FrameLayout에 대해 알아 보았었다. 

▧ 레이아웃이 정의된 frame.xml을 살펴보자. 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
    <Button android:text="Page1" android:id="@+id/btnp1" 
    android:layout_width="wrap_content" android:layout_height="wrap_content" />
    <Button android:text="Page2" android:id="@+id/btnp2" 
    android:layout_width="wrap_content" android:layout_height="wrap_content" />
    <Button android:text="Page3" android:id="@+id/btnp3" 
    android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>  

<FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" >
<LinearLayout android:id="@+id/page1" android:layout_width="fill_parent" 
			  android:layout_height="fill_parent" 
	  		  android:background="#00ff00" android:orientation="vertical"	>
	<TextView  android:layout_width="fill_parent"  android:layout_height="wrap_content"
			   android:textColor="#000000" android:text="기본 아이콘이요~!" />
	<ImageView android:layout_height="wrap_content" android:src="@drawable/icon" 
			   android:id="@+id/img" android:layout_width="wrap_content"/>
</LinearLayout>

<RelativeLayout android:id="@+id/page2" android:visibility="invisible"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent" android:padding="5px"
  android:background="#ffffff"
  android:layout_height="wrap_content">
  
    <ImageView android:layout_height="wrap_content" android:src="@drawable/icon" 
    android:id="@+id/picture" android:layout_width="wrap_content"
    android:layout_alignParentLeft="true" android:layout_marginRight="5px" />
    
    <Button android:text="Del" android:id="@+id/button1" android:layout_below="@id/picture"
    android:layout_width="wrap_content" android:layout_height="wrap_content" />
    
    <TextView android:text="아폴로딸기맛" android:id="@+id/name" android:textColor="#000000"
    android:textSize="12pt" android:layout_alignParentTop="true" 
    android:layout_toRightOf="@id/picture" android:layout_width="wrap_content" 
    android:layout_height="wrap_content" />
    
    <TextView android:text="123-456-7890" android:id="@+id/call" android:textColor="#0000ff"
    android:textSize="6pt"  android:layout_alignParentRight="true"
    android:layout_alignBaseline="@id/name" android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
     
    <TextView android:text="아폴로 딸기맛은 맛있다. 원래 몸에 안좋은게 맛있는거다." 
    android:id="@+id/description" android:textColor="#000000" 
    android:textSize="6pt" android:layout_below="@id/name"
    android:layout_alignLeft="@id/name" android:layout_width="wrap_content" 
    android:layout_height="wrap_content" />
</RelativeLayout>

<TableLayout android:id="@+id/page3"   android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent" 
    android:visibility="invisible" android:stretchColumns="1"
    >
    <TableRow>
    	<TextView android:text="국어" android:padding="3dip" />
    	<TextView android:text="영어" android:padding="3dip" 
    			  android:background="#fff"/>
    	<TextView android:text="수학" android:padding="3dip" />
    </TableRow>
    <TableRow>
    	<TextView android:text="90" android:padding="3dip" />
    	<TextView android:text="91" android:padding="3dip" />
    	<TextView android:text="92" android:padding="3dip" />
    </TableRow>
</TableLayout>
</FrameLayout>
</LinearLayout>

 위의 코드에서 역시 중요한 개념은 FrameLayout 내부의 View 객체들은 모두 왼쪽 상단에 겹쳐서 그려지기 때문에 Visibility가 모두 visible인 상태에서는 가장 먼저 생성된 3페이지만 보이게 될 것이다.(물론 페이지 객체 모두가 한 화면을 가득 채울정도로 크다면, 아니면 샌드위치를 위에서 처다본 것 처럼 될것이다.)

▧ 다음으로 자바 코드는 특별할게 없다. (역시 안드로이드를 하려면 어느정도 자바가 선행 되어야 할 것같다. ) 버튼에 대한 클릭 이벤트 처리만 해주면된다. 

package com.example.MultiPageAndroid;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MultiPageAndroid extends Activity {
	View mPage1, mPage2, mPage3;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frame);
        mPage1 = findViewById(R.id.page1);
        mPage2 = findViewById(R.id.page2);
        mPage3 = findViewById(R.id.page3);
        findViewById(R.id.btnp1).setOnClickListener(mClickListener);
        findViewById(R.id.btnp2).setOnClickListener(mClickListener);
        findViewById(R.id.btnp3).setOnClickListener(mClickListener);
    }
    //anonymous class 선언.
    Button.OnClickListener mClickListener = new Button.OnClickListener(){
		@Override
		public void onClick(View v) {
			mPage1.setVisibility(View.INVISIBLE);
			mPage2.setVisibility(View.INVISIBLE);
			mPage3.setVisibility(View.INVISIBLE);
			
			switch(v.getId()){
			case R.id.btnp1 : mPage1.setVisibility(View.VISIBLE); break;
			case R.id.btnp2 : mPage2.setVisibility(View.VISIBLE); break;
			case R.id.btnp3 : mPage3.setVisibility(View.VISIBLE); break;
			}
		}
    };
}

 위의 코드에서 유심히 볼 것은 xml내부의 속성을 자바 코드로도 접근할 수 있다는 것이다. 다음 시간에 더 자세히 알아 보기로 하고, 출력 결과를 살펴보자. 
  1. 정상적인 출력결과.
    1페이지 2페이지 3페이지

     

     

      
  2. 위에서 잠깐 언급했는데 모든 페이지의 속성을 visible로 주었을 때 출력결과를 살펴보았다.


  3. 정말로 샌드위치가 되어서 출력되었다. 1page는 2page에 가려서 배경색만 나오고있고, 3page는 배경색이 없는 부분은 2page의 내용과 겹쳐서보이고 배경색이있는 영어 부분으로 3page가 가장 위에있다는 것을 확인 할 수 있다.


  이상 Multipage 예제로 android의 layout에 대해 알아보았다.

'Programming > ANDROID' 카테고리의 다른 글

eclipse (Helios)에서 android 개발 코딩 속도 버그 수정  (2) 2011.04.06
setContentView 에 대한 고찰..  (6) 2011.03.30
ViewGroup - RelativeLayout  (2) 2011.03.29
ViewGroup - TableLayout  (1) 2011.03.29
ViewGroup - FrameLayout  (1) 2011.03.28
  1. RelativeLayout은 내부 View들이 서로 상대적인 위치에 따라 배치되어 표시 해 준다. 서로를 인식하기 위해서는 반드시 ID를 정의 해야 한다.
     
  2. 상대적인 위치 인식은 컴파일 시에 가장 먼저 선언된 리소스를 기준으로 배치하기 때문에 절차적으로 선언 해야 한다는 것을 잊지말자. 예를 들어 아래와 같이 A를 B 위에 위치하려면 먼저 B가 ID를 갖고 선언이 되어 있는 상태에서 A는 B의 ID를 참조하여 위에 위치한다는 layout_above 속성값을 가지면 된다.

     
  3. RelativeLayout에 자주 사용되는 속성들은 아래와 같다.

    속 성

    설 명

    android:layout_above

    뷰의 하단 가장자리를 대상뷰의 상단에 붙임(@id/abc)

    android:layout_below

    뷰의 상단 가장자리를 대상뷰의 하단에 붙임(@id/abc)

    android:layout_toLeftOf

    뷰의 오른쪽 가장자리를 대상뷰의 왼쪽에 붙임(@id/abc)

    android:layout_toRightOf

    뷰의 왼쪽 가장자리를 대상뷰의 오른쪽에 붙임(@id/abc)

    android:layout_alignBaseline

    기본적인 위치 는 해당 id를 기준으로 (@id/abc)

    android:layout_centerInParent

    부모뷰의 정중앙에 위치하도록 함(true, false)

    android:layout_centerHorizontal

    부모뷰의 수평 중앙에 배치 (true, false)

    android:layout_centerVertical

    부모뷰의 수직 중앙에 배치 (true, false)

    android:layout_alignParentBottom

    부모뷰의 아래 위치 (true, false)

    android:layout_alignParentLeft

    부모뷰의 왼쪽 위치 (true, false)

    android:layout_alignParentRight

    부모뷰의 오른쪽 위치 (true, false)

    android:layout_alignParentTop

    부모뷰의 상단 위치 (true, false)

     
  4. 간단한 명함을 RelativeLayout으로 표현 해 보자.
    <RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent" android:padding="5px"
      android:background="#ffffff"
      android:layout_height="wrap_content">
      
        <ImageView android:layout_height="wrap_content" android:src="@drawable/icon" 
        android:id="@+id/picture" android:layout_width="wrap_content"
        android:layout_alignParentLeft="true" android:layout_marginRight="5px" />
        
        <Button android:text="ok" android:id="@+id/button1" 
        android:layout_below="@id/picture" android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
        
        <TextView android:text="아폴로" android:id="@+id/name" android:textColor="#000000"
        android:textSize="12pt" android:layout_alignParentTop="true" 
        android:layout_toRightOf="@id/picture" android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
        
        <TextView android:text="123-456-7890" android:id="@+id/call" 
        android:textColor="#0000ff"   android:textSize="6pt"  
        android:layout_alignParentRight="true" android:layout_alignBaseline="@id/name"
         android:layout_width="wrap_content" android:layout_height="wrap_content" />
         
        <TextView android:text="아폴로 딸기맛은 정말 맛있다. 하지만 불량식품이다. 
        						역시 몸에 나쁜것이 더 맛있는 법인가 보다."
        android:id="@+id/description"
        android:textColor="#000000" android:textSize="6pt" android:layout_below="@id/name"
        android:layout_alignLeft="@id/name"
        android:layout_width="wrap_content" android:layout_height="wrap_content" />
        
    </RelativeLayout>
    실행 결과는 아래와 같다.


  5. 처음 레이아웃을 배울 때 html 처럼 <div>로 계속 감싸는 것 처럼 LinearLayout하나를 여러번 사용해 UI툴을 이용해 더 간편히 만들 수 있지 않나 하는 의문이 들었는데, 많은 Layout의 사용은 어플리케이션의 퍼포먼스를 저하시키는 주요 원인이 된다고한다.

'Programming > ANDROID' 카테고리의 다른 글

setContentView 에 대한 고찰..  (6) 2011.03.30
Layout 중첩 - Multi Page  (6) 2011.03.29
ViewGroup - TableLayout  (1) 2011.03.29
ViewGroup - FrameLayout  (1) 2011.03.28
ViewGroup - LinearLayout  (2) 2011.03.28
  1. 테이블 레이아웃은 이름에서 알 수 있듯이 뷰 객체들을 테이블 형태로 행과 열을 맞추어 표시할 수 있게 해 주는 레이아웃이다. 테이블 형태이지만 구분선이 없고 레이아웃의 크기에 한정되어 객체들이 배치되어야 하기 때문에 모든 행의 높이는 wrap_content로 설정되고 한 열의 크기는 가장 큰 객체의 크기에 맞추어 배치된다. 이 때 셀 내용의 크기가 열 폭에 비해 긴 경우는 접어서 표기되기 때문에 적절히 열 폭을 늘리거나 줄이는 작업을 따로 해 줄 필요가 있다.
     
  2. TableLayout의 열에 대한 속성.

    속 성

    의 미

    android:collapseColumns

    숨길 열의 번호

    0부터 시작하는 열의
    번호를
    comma로 구분

    android:shrinkColumns

    숨길 열의 번후

    android:stretchColumns

    늘릴 열의 번호

    android:layout_Columns

    이 뷰가 표시될 열 번호

    android:layout_Columns

    이 뷰가 차지할 열들의 개수


  3. 간단한 성적표를 출력하는 TableLayout을 만들어보자.
    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stretchColumns="1"
        >
        <TableRow>
        	<TextView android:text="@string/kor" android:padding="5dip" />
        	<TextView android:text="@string/eng" android:background="#fff"
        		 android:padding="5dip" />
        	<TextView android:text="@string/mat" android:padding="5dip" />
        </TableRow>
        <TableRow>
        	<TextView android:text="90" android:padding="3dip" />
        	<TextView android:text="91" android:padding="3dip" />
        	<TextView android:text="92" android:padding="3dip" />
        </TableRow> 
    </TableLayout>



     위에서 가운데 영어 성적인 1번째 (0번 부터)열의 크기를 stretchColumns로 늘렸기 때문에 국어,수학 외의 나머지 공간을 모두 채워 넣게 된 것이다. 그리고 padding은 안쪽 여백을 설정 하는 것으로 dip 단위는 해상도에 종속되지 않게 물리적인 화면의 크기에 비례하는 수치이다.

     

'Programming > ANDROID' 카테고리의 다른 글

Layout 중첩 - Multi Page  (6) 2011.03.29
ViewGroup - RelativeLayout  (2) 2011.03.29
ViewGroup - FrameLayout  (1) 2011.03.28
ViewGroup - LinearLayout  (2) 2011.03.28
뷰 그룹(View Group) - Layout  (1) 2011.03.28

+ Recent posts