Things take time

[Android] 프래그먼트! 프레임레이아웃? 본문

Android(기능)

[Android] 프래그먼트! 프레임레이아웃?

겸손할 겸 2019. 1. 23. 17:11

[개요]


안드로이드는 하이브리드 앱만 만들어보니.. 보이지 않은 기능(카메라, 앨범, 푸시 등)만 했었는데, 이젠 온전히 네이티브로 작성된 앱을 유지관리해야하는 일이 되어버렸다..



iOS는 내가 맡아서 시작해서, 이제는 크게 부담스럽진 않지만 이미 상용중인 앱의 유지보수를 하려니, 낯선 것 투성이다.

그래서 기초부터, 자주 사용되는 컴포넌트부터 정리하려 한다.


기존 소스에서 등장한 개념


FrameLayout, ListView, RecyclerView



[Fragment]


https://developer.android.com/guide/components/fragments


공식문서에서 말한다.

액티비티 내에서 사용자 인터페이스의 일부를 말한다. 하나의 액티비티에는 여러개의 프래그먼트가 들어갈 수 있으며, 여러 액티비티에서 하나의 프래그먼트를 재사용할 수 있다. 자체 수명주기를 갖고, 이벤트를 받으며 액티비티 사용중에 추가/삭제가 가능하다.


자체 수명주기를 가지지만, 액티비티에 속하므로 액티비티 수명에 직접 영향을 받게 됨을 의미한다. 액티비티가 실행중이어야 프래그먼트가 추가/삭제가 가능하단 뜻이다.

그리고 뷰 그룹에 속하게 되며, 레이아웃 파일 안에 <fragment>로 선언된다.


간단히 말해, 레이아웃 안에 서브 레이아웃이 들어갈 수 있고, 이 서브레이아웃이 frgment란 태그를 통해 레이아웃 안에 들어간다. 그러므로 각 프래그먼트는 xml로 만들어져야한다. fragment 태그 안의 name속성을 통해 이 프래그먼트 레이아웃과 매핑된다.



[FrameLayout]


얘랑 프래그먼트를 비교하는 이유는 이름이 비슷해서(?), 비슷한 용도일것 같아서 였다.

Fragment는 UI인터페이스의 객체이며, 프레임레이아웃은 말 그대로 레이아웃.. 그 안에 객체들을 갖고있는 집합이다.

리니어 레이아웃이나 기타 레이아웃 처럼 안에 들어오는 UI객체 들을 둘러싼 레이아웃이므로 둘은 전혀, 완전히 다른 성격의 객체이다.


기본적으로 프레임 레이아웃은 하나의 뷰 위젯만을 보여주기 위함이다.


정렬방법에 따른 레이아웃들은 리니어 레이아웃, 렐러티브 레이아웃등이 있는데 프레임레이아웃은 뷰 들을 겹쳐서 보여질 수 있다. 즉, 계층 구조로 그려지게 되며 먼저 XML에 작성한 위젯이 제일 바닥에, 나중에 작성한 위젯이 위로 올라오게 된다. 배경 위젯을 먼저 쓰고, 보여지는 위젯을 나중에 코드로 작성한다면 된다.


프레임레이아웃의 layout_width, layout_height는 wrap_content의 경우 그 레이아웃안에 속한 위젯중 가장 큰 너비, 높이를 가진 객체의 크기를 따라간다.


도움 : https://recipes4dev.tistory.com/127



위와 같이


히히가 제일 위에, XX째지롱이 두번째, 마지막에는 XXXX요? 가 바닥에 있는 것처럼 보인다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="안녕하세요?"
        android:textSize="55dp"
        android:id="@+id/text1"
        android:background="@color/colorAccent"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="두번째지롱"
        android:textSize="40dp"
        android:id="@+id/text2"
        android:background="@color/colorPrimary"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="히히"
        android:textSize="40dp"
        android:id="@+id/text3"
        android:background="@color/colorPrimaryDark"
        />
</FrameLayout>
cs


앞서 말한 것처럼 마지막에 작성한 TextView 위젯이 제일 위에 온다는 것이다.

여기서 배치를 겹치지 않게하려면 layout_gravity 속성으로 변경하면 된다. 이 속성은 현재 이 속성이 들어간 위젯의 바로 상위 레이아웃을 기준으로 어디에 배치시킬 지를 정하는 속성이다.


그러나 프레임레이아웃에서  권장하는 내용은 위젯들을 겹치게 사용하지 말것, 하나의 위젯을 권고하기 때문에 이에 따라 사용법이 나뉜다.


1. 여러 개의 위젯들을 다 만들어놓고 visibility를 invisible, visible을 사용하기

2. FrameLayout을 액티비티 클래스에 연결해서 removeVIewAt(index)로 제거 및 addView(View)로 추가하기


사용되는 종류에는


프래그먼트, 탭 등에서 주로 활용된다고 한다.

실질적으로 사용하는 걸 예를 들면, 카카오톡을 생각하면 된다.


카카오톡 내 대화방에는 여러 타입의 메시지가 있다.


1. 일반 메시지(텍스트 뷰, 날짜 표기, 읽음수 표기 등)

2. 사진 메시지(이미지 뷰, 날짜 표기, 읽음수 표기 등)

3. 파일 메시지(이미지 뷰, 파일 용량 표기, 날짜 표기, 읽음수 표기 등)


이런 식으로 다양한 메시지 타입이 있다. 그러나 그것을 그리는 레이아웃은 대화방 레이아웃 하나다.

그러므로 대화방 레이아웃은 프레임 레이아웃으로 되어있을 것이며, 그 안에는 메시지 타입 코드에 따라 프레임 레이아웃에 있는 위젯의 visibility를 조절하거나, add, remove를 했을 것으로 추측할 수 있다.




https://recipes4dev.tistory.com/58 : 프래그 

https://recipes4dev.tistory.com/127 :프레임

https://dreamaz.tistory.com/345 : 리사이클



[Layout]


UI 컴포넌트를 갖고있는 집합 뷰! 화면이다.

기본적인 레이아웃에는 리니어레이아웃(선형), 렐러티브레이아웃(상대적), 웹뷰 등이 있다. 그런데 이 것들은 정적인 성격의 레이아웃이고, 리스트뷰나 사진첩의 그리드 뷰 같은 동적인 뷰들은 어댑터 뷰의 서브클래스인 레이아웃을 사용하여 런타임, 실행할 때 레이아웃을 채울 수 있다. 어댑터 뷰의 서브(상속받는)클래스는 어댑터를 사용하여 레이아웃 데이터에 바인드하게 된다. 그렇게 해서 데이터를 동적으로 넣게 되는 것이다. ==> 리스트 뷰, 그리드 뷰는 어댑터뷰의 서브클래스이다! 어댑터 뷰는(혹은 어댑터 뷰를 상속받는) 레이아웃을 채우려면 어댑터를 사용한다!



[어댑터 뷰]


어댑터는 여러가지 종류가 있지만, 배열 타입의 데이터를 사용할때는 ArrayAdapter, 커서 타입인 경우의 SimpleCursorAdapter를 사용한다.