FrameLayout (프레임 레이아웃)
Android Developers : developer.android.com/reference/android/widget/FrameLayout )
1. FrameLayout (프레임 레이아웃)
프레임 레이아웃 (FrameLayout)은 여러개의 뷰(View) 위젯들을 중첩하고, 그 중 하나를 전면에 표시할 때 사용하는 레이아웃 입니다. 이렇게 여러 뷰를 겹치게 배치할 수 있는 FrameLayout의 특징이, 뷰 위젯을 겹치지 않고 순서대로 화면에 배치하는 선형 레이아웃(LinearLayout) 과 가장 큰 차이점입니다.
여러 뷰를 중첩하여 배치가 가능하기 때문에 좀 더 다양하게 화면을 구성할 수 있습니다.
액자 속 사진을 마음대로 빼고 넣고 하듯이, 경우에 따라 보여주고 싶은 화면을 자유자재로 스위칭 할 수 있도록 하는 것이FrameLayout 사용 목적입니다.
FrameLayout 을 사용하는 방법은 LinearLayout을 사용하는 것 처럼, 레이아웃 안에 버튼이나 텍스트뷰 등의 자식 뷰 위젯들을 선언해주면 됩니다.
여기서 주의할 점은, FrameLayout 화면에서 가장 전면, 즉 최상단에 보여지는 뷰는 xml 코드에서 가장 마지막에 해당하는 뷰가 배치됩니다. LinearLayout 같은 경우는 xml 에서 코드를 작성한 순서대로 (vertical | horizontal) 화면에 배치가 되는데, FrameLayout은 이와 반대로 xml 코드를 작성한 순서 반대로 화면에 배치가 되어 xml의 가장 마지막으로 뷰가 최상단에 나타나는 것이죠. 1→2→3 순서로 작성했다면, 실제로 화면에 나타나는 것은 3→2→1 순 입니다.
FrameLayout은 아래에서 위로 쌓이는 구조이기 때문에, 아래의 [그림2] 처럼 크기가 다른 뷰를 추가할 때 먼저 넣은 뷰의 일부가 추가된 뷰의 크기만큼 가려집니다.
...
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7">
<View
android:id="@+id/View01"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#990000"/>
<View
android:id="@+id/View02"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#00ff00"
android:orientation="vertical"/>
<View
android:id="@+id/View03"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0000ff"
android:orientation="vertical"/>
</FrameLayout>
...
이런 식으로 FrameLayout 내에서 첫번째로 선언한 View01 은 가장 하단에 배치되고, 마지막으로 선언한 View03은 가장 상단에 배치됩니다.
별 건 아니지만 한번씩 뇌정지가 올 때가 있으니 주의하세요..
2. Visible 설정하기
위에서 FrameLayout은 경우에 따라 보여주고 싶은 화면을 자유자재로 스위칭 할 수 있다고 했습니다.
FrameLayout을 사용할 때 Visibility 속성을 이용한다면 화면을 보다 효과적으로 나타낼 수 있습니다.
Visibility 로 뷰의 가시성을 설정할 수 있습니다. 크게 세가지 속성이 있습니다.
- visible : 뷰의 영역을 유지하고, 뷰를 보여줍니다. 대부분 뷰의 일반적인 상태입니다.
- invisible : 뷰의 영역은 유지하되, 뷰를 숨겨 보이지 않게 됩니다. 예를 들어, 이미지뷰의 영역은 남기고 이미지를 숨기는 것이죠.
- gone : 뷰의 영역 자체를 숨겨버려 뷰가 보이지 않게 됩니다.
▶ activity_main.xlm
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/firstBtn"
android:text="1"
android:onClick="onClick"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/secondBtn"
android:text="2"
android:onClick="onClick"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/thirdBtn"
android:text="3"
android:onClick="onClick"/>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7">
<View
android:id="@+id/View01"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#990000"
android:visibility="invisible"/>
<View
android:id="@+id/View02"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#00ff00"
android:visibility="invisible"/>
<View
android:id="@+id/View03"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0000ff"
android:visibility="invisible"/>
</FrameLayout>
</LinearLayout>
▶ MainActivity.java
package com.example.viewactivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements Button.OnClickListener{
private View firstView;
private View secondView;
private View thirdView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
// 뷰 초기화
public void init() {
firstView = findViewById(R.id.View01);
secondView = findViewById(R.id.View02);
thirdView = findViewById(R.id.View03);
}
@Override
public void onClick(View v) {
switch(v.getId()){
// 첫번째(red) 뷰만 보이기
case R.id.firstBtn :
firstView.setVisibility(View.VISIBLE);
secondView.setVisibility(View.INVISIBLE);
thirdView.setVisibility(View.INVISIBLE);
break;
// 두번째(green) 뷰만 보이기
case R.id.secondBtn :
secondView.setVisibility(View.VISIBLE);
firstView.setVisibility(View.INVISIBLE);
thirdView.setVisibility(View.INVISIBLE);
break;
// 세번째(blue) 뷰만 보이기
case R.id.thirdBtn :
thirdView.setVisibility(View.VISIBLE);
firstView.setVisibility(View.INVISIBLE);
secondView.setVisibility(View.INVISIBLE);
break;
}
}
}
xml 에서 View01, View02, View03 모두 visibility를 invisible로 설정해놓았기 때문에, FrameLayout 안에 뷰의 영역 자체는 존재하지만 아무것도 나타나지 않습니다.
java 코드를 살펴봅시다.
1_Red 버튼을 누르면 firstView.setVisibility(View.VISIBLE); 로 인해서 View01만 visible로 설정되어 화면에 나타납니다.
2_Green, 3_Blue도 같은 방식으로 누르는 버튼에 따라 가시성 세팅이 바뀌면서 각각의 화면이 표시됩니다.
이처럼 동일한 화면 영역에 경우에 따라 다른 화면을 표시하고 싶을 때, 레이아웃을 새로 파는것 보다 FrameLayout을 사용한다면 좀 더 편하고 효과적으로 나타낼 수 있겠죠?
('뽀따'님 블로그를 참고하여 정리하였습니다. recipes4dev.tistory.com/127 )
3. 활용
제가 FrameLayout을 활용했던 케이스는, 서버에서 데이터를 받아와서 리스트에 뿌려주는 게 있었는데, 서버에 데이터가 없을 경우 데이터가 없을 경우 리스트 조회 화면 대신 "조회할 데이터가 없습니다" 라는 화면이 뜨도록 했습니다.
아래 이미지는 예시 이미지로서 제가 만든 화면은 아니지만 이런 식으로 만들었다라고 봐주시면 되겠습니다.
개발 공부를 한지 얼마 되지 않아서 FrameLayout 을 많이 써본 적은 없으나, 잘 활용하면 편리한 뷰라고 생각됩니다.
'Study > Android' 카테고리의 다른 글
Unit 1-Pathway4-4 : 주사위 앱에 이미지를 추가해보자 (0) | 2022.05.10 |
---|---|
ImageView without contentDescription 경고 (앱의 접근성 확인) (0) | 2022.04.21 |
Android 문자열 리소스, 하드코딩된 문자열 (strings.xml) (0) | 2022.04.21 |
네이버 지도 SDK 빌드 오류 해결 (Failed to resolve/Migrate to Androidx) (0) | 2022.04.13 |
[Android Studio/Java] LinearLayout (선형레이아웃) 사용하기 (0) | 2021.01.12 |