안드로이드 인터페이스 기초 02 - 레이아웃 (Layout)

Dora·2020년 11월 5일
0

Chap5. 인터페이스 기초02 - 레이아웃(Layout)

Layout

: 뷰그룹의 일종으로 다른 view들을 내부에 배치하는 컨테이너 역할을 수행한다.

; 일반적으로 화면상에 직접 보이지 않는다.

; 주요 레이아웃 : Linear/Relative/Frame/Grid/ConstraintLayout

LinearLayout

: 가장 간단한 레이아웃으로 가로(horizontal) 또는 세로(vertical)의 순서대로 항목을 배치한다.

; 절대 선택한 방향으로 배치된다. (뷰가 차고넘쳐도)

주요 속성

  • orientation
    : vertical/horizontal

  • gravity
    : 내부 항목의 수직/수평 배치 결정
    (내가 내부에 담고있는 항목의 정렬)

  • layout_gravity
    : 레이아웃에 항목 자신의 수직/수평 방향 배치 결정
    (내가 담겨져 있는 레이아웃에서의 정렬)

  • baselineAligned
    : 레이아웃에 배치한 뷰들의 아래 부분 맞춤 활성화 여부 (기준선)

  • layout_weight
    : 레이아웃의 공간을 어느 정도 비중으로 차지하느냐를 결정.
    0일 경우 본래 크기, 1 이상이면 다른 뷰와의 비율에 따라 배치된다.

  • layout_margin
    : 레이아웃과 뷰 사이의 간격.

  • padding
    : 뷰와 내부 내용물 사이의 간격.

RelativeLayout

: 뷰와 뷰를 담고 있는 레이아웃(부모뷰), 그리고 다른 뷰와의 상대적인 관계로 배치한다.

; id가 필수로 요구된다.

FrameLayout

: 레이아웃의 좌측 상단에 모든 뷰들을 겹쳐서 배치한다.

; app 실행 중 addView/removeView 메소드를 사용하여 뷰들을 추가 및 삭제.
; 뷰의 visibility 속성을 이용하여 한 화면에서 여러 화면을 번갈아 보여주고 싶을 때 사용한다.

그 외 레이아웃

AbsoluteLayout

: 배치하는 View의 좌표를 절대값으로 지정한다.

; Realative와 상반된 개념.
; 기기별로 다양한 해상도를 갖기 때문에 사용이 적합하지 않아 거의 쓰이지 않음.

TableLayout

: 표 형식으로 View를 내부에 배치.

; 가로 : TableRow의 개수만큼 행 생성
; 세로 : TableRow에 포함한 View의 개수만큼 열 생성

ConstraintLayout

제약이 있는 레이아웃. 레이아웃의 가로, 세로에 뷰를 연결한다.
현재 안드로이드에서 가장 기본적으로 쓰이는 레이아웃.

레이아웃의 중첩

: 레이아웃 안에는 뷰 뿐만 아니라 다른 레이아웃을 중첩하여 배치 가능하다.

; 한 화면에 여러 개의 레이아웃이 가능하다는 말.
; 레이아웃은 보이지 않기 때문에 component tree상에서 옮기는 게 편하다.

실행 중 레이아웃 속성 변경

: XML로 지정한 레이아웃 속성은 소스코드 실행 중 변경 가능하다.

1. XML로 지정한 뷰 객체를 찾은 후 변경 메소드 호출

ex. xml에서 지정한 id가 LinearLayout1인 레이아웃을 객체화

LinearLayout layout = (LinearLayout)findViewbyId(R.id.LinearLayout1);
  • findViewById() 메소드
    : xml로 정의하여 자동 변환된 뷰 요소를 찾기 위한 메소드
    ; View 객체 형태로 반환하므로 타입캐스팅이 필요하다. (필수는 아님)
    ; Activity.findViewById()는 Activity 내부의 모든 뷰에서 id를 검색하는 것이고, View.findViewById()는 특정 뷰 내부에서만 검색하는 것이다.

2. 객체화한 뷰 객체에서 속성에 해당하는 메소드 호출

ex1. LinearLayout의 orientation을 수평으로 바꾸고 싶을 때

layout.setOrientation(LinearLayout.HORIZONTAL);

ex2. LinearLayout의 현재 orientation을 확인하고 싶을 때

int o = layout.getOrientation();

대부분의 경우 속성에 해당하는 getter/setter가 존재한다.

예를 들어 orientation 속성을 확인하거나 변경하려면 속성앞에 set/get을 붙여 setOrientation/getOrientation으로 표현할 수 있다.

get으로 값을 받을 때에는 임의의 값이나 정해진 상수값으로 지정해서 받는다.

UI 작성 방법

XML 레이아웃을 이용할 경우

//MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
    	setContentView(R.layout.activity_main);
}

//activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
	<TextView
    		android:id="@id/textView1"
            	android:layout_width="wrap_parent"
                android:layout_height="wrap_parent"
                android:text="TextView" />
</LinearLayout>
    		

코드만으로 작성할 경우

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
    	
        LinearLayout linear = new LinearLayout(this);
        linear.setOrientation(LinearLayout.VERTICAL);
        linear.setBackgroundColor(Color.LTGRAY);
        
        TextView text = new TextView(this);
        text.setText("TextView");
        text.setGravity(Gravity.CENTER);
        
        linear.addView(text);
        setContentView(linear);
}
  • 두 가지 경우 setContentView를 사용하여 레이아웃을 연결하는 것은 같지만 해당 메소드의 매개변수는 다르다. (오버로딩)

*오버로딩(Overloading) : 메소드 이름은 같고, 매개변수의 개수, 타입이 다른 여러 개의 메소드 정의. (반환 타입 영향X)

레이아웃 전개(inflation)

: XML로 지정한 뷰는 aapt에 의해 컴파일되어 이진 형태의 자바 객체로 변환된다.
*aapt(Android Asset Packaging Tool)

inflation

: XML문서의 텍스트 형태의 뷰를 실제 자바 객체화 하는 것.

; XML로 정의하면 자동으로 자바 객체로 변환된다. (R에 id가 등록됨)
; Inflation 진행 후 findViewById()메소드로 해당 객체 참조 가능.

setContentView() 메소드

: View를 전달받아 Activity에 등록하는 역할.

경우1. 레이아웃의 resource id를 매개변수로 전달받으면 내부에서 inflation을 수행한 후 Activity에 등록한다. (==XML이용)

경우2. View객체(및 params객체)를 전달받으면 View를 params 정보에 따라 Activity에 등록. (==코드에 직접)

Inflation 직접 실행

직접 inflation을 수행해야하는 경우가 있다.
ex. 앱 실행 중 화면의 구성을 바꾸어야 할 때
ex2. 상황에 따라 서로 다른 화면 구성이 교체되어야 할 때

방법1. inflater를 생성하여

LayoutInflater Inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout linear = (LinearLayout)inflater.inflate(R.layout.activity_main, null);
setContentView(linear);
  • LayoutInflater Inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    : 시스템이 제공하는 기본 서비스를 요청하는 메소드

//LayoutInflater Inflater = LayoutInfalter.from(this);
: 위 코드와 동일한 내용, 다른 생김새. this는 Context객체다. (Activity 자신)

  • LinearLayout linear = (LinearLayout)inflater.inflate(R.layout.activity_main, null);
    : null 자리에는 root view(부모뷰)가 있을 경우 지정한다.

방법2. inflater 없이

LinearLayout linear = (LinearLayout)View.inflate(this, R.layout.activity_main, null);
setContentView(linear);

// View가 갖고있는 정적 메소드 inflate를 사용한다.

Layout Parameter

: view가 레이아웃 상에 배치되는 정보를 지정한다.

; XML상에서 layout_XXX형태의 속성들
; 뷰 자체의 속성이 아닌 외부 레이아웃에 배치할 때 필요한 정보
; 각 레이아웃마다 사용하는 정보가 다르므로 레이아웃에 배치할 때 뷰와 함께 매개변수로 전달한다.

ex.

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
	LinearLayout.LayoutParams.WRAP_CONTENT, 
    	LinearLayout.LayoutParams.WRAP_CONTENT);
        
linear.addView(text, params);

profile
Lv.1 개발자

0개의 댓글