레이아웃은 앱에서 사용자 인터페이스를 위한 구조(Activity 등)를 결정.
Android는 위젯, 레이아웃과 같이 View 클래스와 서브클래스에 상응하는 간단한 XML 문법을 통해 선언한다. Android Studio의 Layout Editor를 사용해서 마우스로 드로그 앤 드롭으로도 빌드할 수 있지만 보통 키보드로 빌드한다.
직접 프로그래밍하여 View 및 ViewGroup객체를 만들고 그 속성을 따로 선언, 조작할 수 있다.
XML에서 UI를 선언하면 동적제어 코드로 앱 표현을 분리할 수 있다. 또한 XML 파일을 사용하면 다양한 화면 크기와 방향에 여러가지 레이아웃을 쉽게 제공할 수 있다.
위 두가지를 모두 사용하여 앱의 UI를 빌드할 수 있다. 예를 들어 앱의 기본 레이아웃을 XML에서 선언한 다음, 런 타임에 레이아웃을 수정할 수 있다.
XML 어휘를 사용하여 UI Layout과 화면 요소를 중첩된 요소를 사용하는 방식으로 디자인.
각 Layout 파일에는 반드시 단 하나의 루트 요소만 있어야 -> View OR ViewGroup 객체. 루트 요소를 정의하고 더 많은 레이아웃 객체 또는 위젯을 하위 요소로 계층적 레이아웃 정의하는 View 계층 구조를 빌드할 수 있다.
아래 코드는 수직 LinearLayout 을 사용해 하위 요소로 TextView와 Button을 사용한 XML 레이아웃
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView" />
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button" />
</LinearLayout>
앱을 컴파일할 때 각 XML 레이아웃 파일이 View 리소스 안에 컴파일된다. Activity.onCreate() 콜백 구현해서 레이아웃 리소스를 로드해야 한다. 이 떄 setContentView()를 호출하고 R.layout.main_layout
의 형태로 참조한다. (Resource에 있는 layout 중 main_layout을 참조한다는 의미. 이때 main_layout 자리에 해당 레아아웃의 이름이 들어간다.)
아래 코드에서는 Activity가 시작될 때 main_layout이 View로 보여진다는 의미.
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
}
모든 View와 ViewGroup 객체는 고유한 여러가지 XML 속성을 지원.(예_ ID, 레이아웃 매개변수, 위치정보, 크기, padding, margin 등) 물론 어떤 속성은 View 객체에만 적용되고(textSize), 어떤 속성은 ViewGroup 객체에 적용된다(ID).
모든 View 객체는 뷰를 고유하게 식별할 수 있는 Integer ID를 연결될 수 있다.
android:id="@+id/my_button"
와 같이 사용한다.
안드로이드 프레임워크는 다른 ID 리소스도 많이 제공한다. 안드로이드 리소스 ID를 참조할 때는 '+' 기호는 필요하지 않지만 adroid 패키지 라는 것을 반드시 알려주어야 한다.
android:id="@android:id/empty"
android 패키지 네임스페이스가 들어가면 로컬 리소스 클래스가 아니라 android.R
리소스 클래스에서 ID를 참조한다.
일반적으로 뷰를 생성하고 이를 앱에서 참조할 때는 아래와 같은 패턴
1. 레이아웃 파일에서 뷰/위젯을 정의, ID 할당
<Button android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
val myButton: Button = findViewById(R.id.my_button)
id는 트리 전체를 통틀어 고유할 필요는 없지만 트리에서 검색하는 부분 내에서는 고유해야 한다. 트리 전체를 검색할 경우가 잦으므로 왠만하면 고유한 것 사용하자.
Layout의 종류에 따라 View가 있는 ViewGroup에 적절한 View 레이아웃 매개변수를 정의할 수 있다.
즉, 상위 뷰 그룹이 각 하위 뷰의 레이아웃 매개변수를 정의한다. 물론 하위요소에 각기 다른 LayoutParams도 정의할 수 있다.
너비와 높이도 정확한 치수로 정할 수 있지만 보통 wrap_content나 match_parent로 설정한다.
뷰는 직사각형이다. 위치는 한쌍의 왼쪽 및 상단 좌표, 두개의 치수가 너비와 높이를 나타내는 형식[pixel]
뷰의 위치는 getLeft() 및 getTop() 메서드로 검색할 수 있다. 만약 getLeft()가 20을 리턴한다면 뷰가 그 뷰의 부모의 왼쪽 가장자리에서 오른쪽으로 20pix 떨어진 곳에 있다는 의미.
그 외 getRight() (= getLeft() + getWidth() ) , getBottom() 계산
layout_height : 세로 길이
layout_width : 가로 길이
layout_margin : View와 상위 레이아웃 사이의 공간(바깥 쪽에 해당 크기만큼의 공간이 생김)
padding : View와 View 안의 내용 사이의 공간 (안쪽에 해당 크기만큼의 공간이 생김.)
layout_gravity : 상위 레이아웃에서의 위치 정렬 (or연산자('|')를 이용해서 혼합 사용가능)
gravity : 해당 속성에서의 하위 속성 위치 정렬
UI 디자인을 달성하기 위해 하나 이상의 레이아웃을 다른 레이아웃 안에 중첩 가능, 하지만 최대한 중첩을 적게!! 얕을수록 레이아웃이 더 빠르게 그려진다. (가로로 넓은 것이 세로로 깊은 계층보다 좋다)
- linearLayout
Linear : "선형의" -> 말그대로 레이아웃 안의 요소들을 가로 OR 세로 방향으로 선형적으로 나열 할 수 있다.
1) orientation : 요소들이 나열되는 방향을 지정해준다. 지정할 수 있는 방향으로 horizontal(가로), vertical(세로)가 있다.
2) layout_weight : 가중치를 의미한다. 요소들을 나열할 때 화면의 크기에 비례해서 요소의 크기를 결정할 때 사용한다.
3) weightSum : 가중치의 합을 의미한다. 가중치를 주어서 요소를 나열할 때 공백을 구성하고 싶을 때 사용한다.
- RelativeLayout
Relative : "상대적인" -> 레이아웃의 요소들을 상대적으로 나열하고 싶을 때 유용하게 사용.
1) 뷰와 뷰 사이의 상대적인 위치를 결정할 때
2) 부모인 RelativeLayout 기준으로 상대적인 위치를 결정할 때
3) 맞춤 정렬을 하고자 할 때
- FrameLayout
Frame : "액자" -> 액자에 사진을 꽂아놓고 보관하는 것처럼 여러개의 뷰를 바꿔가면서 화면에 표시할 수 있다.
1) 안드로이드에서는 특정한 이유가 없는 한 FrameLayout이 오직 하나의 뷰만 표시학 만들도록 권고.
(FrameLayout 안에 크기가 다른 뷰들을 겹치지 않게 구성하는 것이 어렵다네요)
2) 가장 마지막에 추가된 뷰가 전면에 표시됨.
3) addView(), removeView(), LayoutInflater, visibility,setVisibility
- GridLayout
자식을 직사각형 그리드에 배치하는 레이아웃.
그리드는 보이는 연역을 셀로 구분하는 선 집합으로 구성됨.
- TableLayout
Table : "표" -> 표처럼 사용할 수 있으며 열(Coulmn), 행(Row)로 표현된다.
1) TableRow 라는 요소를 사용하여 행(Row)을 추가할 수 있다.
2) TableRow 안에 View를 선언하여 열(column)을 추가할 수 있다.
- DrawerLayout
Drawer : "서랍" -> 화면을 서랍처럼 열고 닫는 기능을 한다.
1) DrawerLayout을 사용하기 위해서는 사용할 요소(View,TextView)가 자식(child)으로 추가되어 있어야 한다.
2) 추가로 어느 방향에서 열릴지 layout_gravity값이 설정되어 있어야 한다.
2) xml 파일을 새로 생성하여 DrawerLayout을 구현하든 DrawLayout 안에 TextView를 생성하든 DrawerLayout에서 제공하는 함수의 원형을 보면 두 개가 같다는 것을 알 수 있다.
3) openDrawer(), closeDrawer()
- ConstraintLayout
Constraint : "제약" -> 여러가지 제약 조건들을 이용해서 뷰의 크기와 위치를 결정
RelativeLayout의 "상대적인 위치 관계", LinearLayout의 "가중치" , Chain의 "요소 그룹화" 의 특징을 가짐.
1) Relative positioning : 상대 위치 지정 관련 속성
2) Margins :( layout_margin외에 대상 View 가보이지 않는 View.gone 상태일 때 여백 속성.(goneMargin)
3) Centering positioning and bias : bias 는 치우침. 수평/수직 방향으로 사이드 제약을 걸 때 사이드간 위치 비율을 지정.
4) Circular positioning : 원형 위치 지정은 대상 뷰의 id 와 거리, 각도값을 입력하여 나타낼 수 있다.
5) Visibility behavior : Visibility ㅡ특성과 Margins의 goneMargin 특성을 포함
6) Dimension constraints : 위젯의 크기를 조정하는데 유용하게 사용된다.
7) Chains : 가로/세로축에 대해 view들을 그룹지울 수 있다. 인접한 view끼리 서로 쌍방향 constraint 정의되어있을 때 cahin 관계에 있다고 본다.
8) Virtual Helper objects : 안드로이드는 ConstraintLayout이 사용을 돕기 위해 특별한 객체 몇가지 제공
Guideline, Group, Barrier 등
9) Optimizer : 제약 카테고리에 대한 최적화 기능.
출처:
![안드로이드 레이아웃]https://recipes4dev.tistory.com/66?category=658689
![안드로이드 레이아웃 공통사항]https://recipes4dev.tistory.com/87?category=658689
https://developer.android.com/guide/topics/ui/declaring-layout