240102 TIL #284 Android #7 Layout

김춘복·2024년 1월 2일
0

TIL : Today I Learned

목록 보기
284/543
post-custom-banner

Today I Learned

이번주는 쭉 안드로이드 공부!


Layout

화면을 독자적으로 출력하지 않고 다른 뷰 객체를 포함하는 일종의 그릇 역할

LinearLayout

뷰를 가로나 세로방향으로 나열하는 클래스.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>
  • orientation 속성에 horizontal(가로), vertical(세로)로 방향을 지정

  • 가로 세로가 섞인 레이아웃을 원한다면 레이아웃을 계층화해서 LinearLayout 안에 LinearLayout으로 가로 세로를 섞어 구성하면 된다.

layout_weight 속성

여백을 뷰로 채울 수 있는 속성

  • layout_weight 속성의 숫자를 통해 남은 여백을 뷰로 가중치에 따라 채우는걸 조절할 수 있다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="BUTTON1"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:text="BUTTON2"/>

</LinearLayout>
  • 아래의 그림에서 첫번째는 layout_weight가 없을 때, 두번째는 버튼1만 layout_weight 1일때, 세번째는 버튼1이 1, 버튼2가 2일때의 모습이다.

  • 가로 세로 레이아웃이 중첩된 상황에서는 layout_weight을 적용 시, 같은 영역에 있는 뷰 끼리만 여백을 나누어 차지한다.

  • 아래와 같이 뷰의 크기를 0으로 하고(layout_height="0dp"), layout_weight만 값을 설정해 화면을 비율에 맞게 분등하기도 한다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="BUTTON1"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="BUTTON2"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="BUTTON3"/>

</LinearLayout>

gravity, layout_gravity

뷰를 정렬할 때 사용하는 속성

  • 미설정 시, 디폴트 값은 left, top으로 왼쪽 위를 기준으로 기본적으로 정렬된다.

  • gravity : 정렬 대상은 콘텐츠.

  • layout_gravity : 정렬 대상은 뷰 자체.

    <TextView
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:background="#FF0000"
        android:text="HelloWorld"
        android:textSize="15dp"
        android:textColor="#FFFFFF"
        android:textStyle="bold"
        android:gravity="right|bottom"
        android:layout_gravity="center_horizontal"/>

  • 위의 예시에서 gravity="right|bottom"으로 콘텐츠인 문자열이 우측 하단에 정렬 되어있고, layout_gravity="center_horizontal"으로 빨간 배경의 뷰 자체가 가로로 가운데에 정렬되어 있다.

  • layout_gravity는 layout 자체가 세로일땐 가로만, layout 자체가 가로일땐 세로로만 정렬이 가능하다.
    즉, LinearLayout의 orientation에서 설정한 방향과 같은 방향으로는 설정되지 않는다.

  • 아예 LinearLayout의 정중앙에 정렬하려면, LinearLayout 코드 안에서 android:gravity="center"로 설정해야 한다. (LinearLayout의 콘텐츠가 view이므로)


RelativeLayout

상대 뷰의 위치를 기준으로 정렬하는 레이아웃 클래스
android:layout_위치="@+id/아이디"

배치 규칙

android:layout_above : 기준 뷰의 위쪽에 배치
android:layout_below : 기준 뷰의 아래쪽에 배치
android:layout_toLeftOf : 기준 뷰의 왼쪽에 배치
android:layout_toRightOf : 기준 뷰의 오른쪽에 배치

사용방법

  • 기준이 되는 뷰에 id 부여 후, 배치하려는 뷰에 아이디 입력후 위치 설정.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image1"
        android:text="Hello"/>
</RelativeLayout>

align 속성

  • 상대 뷰의 어느쪽에 맞춰 정렬할 지 정할 수 있다.

    android:layout_alignTop : 기준 뷰와 위쪽에 맞춰 정렬
    android:layout_alignBottom : 기준 뷰와 아래쪽에 맞춰 정렬
    android:layout_alignLeft : 기준 뷰와 왼쪽에 맞춰 정렬
    android:layout_alignRight : 기준 뷰와 오른쪽에 맞춰 정렬
    android:layout_alignBaseline : 기준 뷰와 텍스트 기준 선에 맞춰 정렬

  • 상위 레이아웃을 기준으로 맞출 수 있다.

    android:layout_alignParentTop="true" : 부모의 위쪽에 맞춤
    android:layout_alignParentBottom="true" : 부모의 아래쪽에 맞춤
    android:layout_alignParentLeft="true" : 부모의 왼쪽에 맞춤
    android:layout_alignParentRight="true" : 부모의 오른쪽에 맞춤
    android:layout_centerHorizontal="true" : 부모의 가로방향 중앙에 맞춤
    android:layout_centerVertical="true" : 부모의 세로방향 중앙에 맞춤
    android:layout_centerInParent="true" : 부모의 가로, 세로 중앙에 맞춤


FrameLayout

뷰를 겹쳐서 출력하는 레이아웃 클래스.

  • FrameLayout을 사용하면 뷰끼리 겹쳐서 출력된다.

  • 단순히 겹쳐서 출력되므로 특별한 속성은 없다.

  • 똑같은 위치에서 여러 뷰를 겹쳐두고, 순간마다 하나의 뷰만 출력할 때 주로 사용한다.
    ex) 탭화면 생성하고 탭의 상태에 따라 거기에 맞는 화면 출력

  • 대부분 visibility 속성(뷰의 표시 여부 설정)과 함께 사용해, 처음에는 invisible한 속성을 이벤트에 따라 visible하게 보일 수 있게 자주 쓰인다.


GridLayout

행과 열로 구성된 테이블 화면을 만드는 레이아웃 클래스

  • orientation : horizontal과 vertical 방향 설정

  • rowCount : 세로로 나열할 뷰 개수

  • columnCount : 가로로 나열할 뷰 개수

사용 방법

  • GridLayout에 추가한 뷰는 크기가 기본적으로 wrap_content로 지정되므로 layout_height와 layout_width를 설정하지 않아도 된다.
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:columnCount="3">
    <Button android:text="A"/>
    <Button android:text="B"/>
    <Button android:text="C"/>
    <Button android:text="D"/>
    <Button android:text="E"/>
</GridLayout>

  • 뷰에서 layout_row와 layout_column 속성으로 특정 뷰의 위치를 직접 지정할 수 있다. 0부터 시작하는 인덱스값 기준이다.

  • layout_rowSpan, layout_columnSpan을 통해 행과 열 병합도 가능하다.


ConstraintLayout

안드로이드 플랫폼이 아닌 androidx에서 제공하는 라이브러리
안드로이드 스튜디오에서 코드가 아닌 마우스로 레이아웃을 구성할 수 있다.

  • 우선 build.gradle에 아래와 같이 선언되어 있어야 한다.
    (보통은 안드로이드 프로젝트 생성시 자동으로 추가된다.)
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
  • Android Studio의 디자인 에디터에서 ConstraintLayout을 사용하면 시각적으로 레이아웃을 디자인할 수 있다. 드래그 앤 드롭으로 뷰를 배치하고, 제약 조건을 설정하며, 레이아웃을 쉽게 조정할 수 있다.

사용방법

  • 왼쪽의 팔레트에서 원하는 종류의 뷰를 선택해 드래그 앤 드롭으로 액티비티 화면에 끌고 온다.

  • 오른쪽의 Attributes에서 id, layout_width, layout_height를 설정한다.

  • constraints(제약조건)에서 가로와 세로 제약조건을 어디에 고정할 것인지 설정해야 한다. layout에서 마진을 설정할 수 있다.

예시

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@tools:sample/avatars" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:text="카카오톡"
        app:layout_constraintStart_toEndOf="@+id/imageView1"
        app:layout_constraintTop_toTopOf="@+id/imageView1" />

    <TextView
        android:id="@+id/messageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:text="[기기 로그인 알림]"
        app:layout_constraintBottom_toBottomOf="@+id/imageView1"
        app:layout_constraintStart_toEndOf="@+id/imageView1" />

    <TextView
        android:id="@+id/dateView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="350dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="1월 1일"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


profile
Backend Dev / Data Engineer
post-custom-banner

0개의 댓글