안드로이드 프레임레이아웃 뷰 변경하기 1. [addView(), removeView()] (How to change a View in Android FrameLayout)
1. FrameLayout에 표시되는 뷰 변경하는 방법
[안드로이드 프레임레이아웃(Android FrameLayout)]에서 설명했듯이, FrameLayout
은 자식(Children)으로 추가된 여러 뷰(View) 위젯들 중 하나를 Layout의 전면에 표시할 때 사용하는 Layout 클래스입니다. 그리고 안드로이드에서는 FrameLayout
이 오직 하나의 자식(Child) 뷰 위젯만을 표시하게 만들도록 권고하고 있죠.
FrameLayout
에 하나의 뷰(View)만을 표시하는 방법은, addView() 및 removeView()를 사용하여 FrameLayout
이 하나의 뷰(View)만을 가지게 만들거나, FrameLayout
에 여러 자식(Children) 뷰 위젯을 추가해두고 자식(Child) 뷰 위젯의 visibility 속성을 사용하여 하나의 뷰(View)만 화면에 보이도록 만드는 방법이 있습니다.
여기서는 두 가지 방법 중, addView() 및 removeView() 함수를 사용하여 하나의 뷰(View)만 가지도록 만드는 방법에 대해 살펴보겠습니다.
2. addView() 함수와 removeView()
FrameLayout
에 뷰(View)를 추가하는 함수는 addView() 함수입니다. addView() 함수를 사용하여 여러 개의 뷰(View)를 추가하면, 마지막으로 추가된 뷰(View)가 FrameLayout
의 전면에 표시됩니다. "액자"의 제일 앞에 사진을 끼우는 것처럼 말이죠. 또한 addView() 함수는 파라미터가 다른 여러 함수가 오버로딩(overloading)되어 있습니다.
함수명 | 설명 |
---|---|
addView(View child, ViewGroup.LayoutParams params) |
params 설정을 가진 child 뷰 추가. |
addView(View child, int index) | index 위치에 child 뷰 추가. |
addView(View child, int index, ViewGroup.LayoutParams params) |
params 설정을 가진 index 위치에 child 뷰 추가. |
addView(View child) | chlid 뷰 추가. |
addView(View child, int width, int height) | width x height 크기를 가진 child 뷰 추가. |
FrameLayout
에서 뷰(View)를 삭제하는 함수는 removeView() 함수입니다. 그런데 removeView() 함수는 파라미터가 다른 동일한 함수가 존재하지 않습니다. 대신, 기능에 따라 구분된 다른 이름의 함수가 정의되어 있습니다.
함수명 | 설명 |
---|---|
removeAllViews() | FrameLayout에 포함된 모든 자식(Children) 뷰 제거. |
removeAllViewsInLayout() | FrameLayout 내부에서 모든 자식(Children) 뷰 제거. |
removeView(View view) | FrameLayout에서 view 제거. |
removeViewAt(int index) | FrameLayout의 index 위치 자식(Child) 뷰 제거. |
removeViewInLayout(View view) | FrameLayout 내부에서 view 제거. |
removeViews(int start, int count) | FrameLayout의 start 위치부터 count 갯수만큼 자식(Children) 뷰 제거. |
removeViewsInLayout(int start, int count) | FrameLayout에서 start 위치부터 count 갯수만큼 자식(Children) 뷰 제거. |
3. FrameLayout 뷰(View) 변경하기
그럼 이제 예제를 통해, addView()와 removeView() 함수를 사용하여 FrameLayout
에 표시되는 뷰(View)를 변경하는 방법에 대해 살펴보겠습니다.
예제에서 작성하는 화면은 아래와 같은 레이아웃으로 구성됩니다.
참고로 예제 소스에서는, 코드의 쉬운 이해를 위해 FrameLayout
에 표시될 뷰(View)들을 개별적인 변수로 선언하였습니다. 하지만 개별 변수로 선언하는 방법은, 전환될 뷰(View)가 많아지면 구현 및 관리가 용이하지 않습니다. 그래서 개선된 코드를 주석에 같이 기록하였으며, "개선된 코드"라는 주석에서 확인할 수 있습니다.
3.1 MainActivity의 레이아웃 구성.
예제 작성을 위해 가장 먼저 할 일은, 앞서 설계한 화면에 따라 MainActivity에 표시될 레이아웃 리소스 XML을 작성하는 것입니다.
[STEP-1] "activity_main.xml" - MainActivity의 Layout 구성.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.recipes4dev.examples.framelayoutchangingview1.MainActivity"
tools:showIn="@layout/activity_main">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/linear">
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Text 1" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Text 2" />
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Text 3" />
</LinearLayout>
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/frame"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linear"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#4CAF50"
android:gravity="center"
android:id="@+id/text1"
android:text="TEXT 1" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF9800"
android:gravity="center"
android:id="@+id/text2"
android:text="TEXT 2" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#009688"
android:gravity="center"
android:id="@+id/text3"
android:text="TEXT 3" />
</FrameLayout>
</android.support.constraint.ConstraintLayout>
3.2 각 버튼 클릭 이벤트 처리.
화면에는 세 개의 버튼이 있고, 각 버튼을 클릭하면 순서에 따른 텍스트뷰가 화면에 표시됩니다. 이를 위해 각 버튼의 클릭 이벤트를 작성합니다. 단, 실질적인 FrameLayout
의 뷰(View) 변경은 다음 단계에서 changeView() 라는 함수에 작성하고, 버튼 클릭 이벤트 핸들러에서는 changeView() 함수를 호출하도록 만듭니다.
[STEP-2] "MainActivity.java" - onCreate() 함수에서 각 버튼 클릭 이벤트 처리.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// ... 코드 계속
Button button1 = (Button) findViewById(R.id.button1) ;
button1.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
changeView(0) ;
}
});
Button button2 = (Button) findViewById(R.id.button2) ;
button2.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
changeView(1) ;
}
});
Button button3 = (Button) findViewById(R.id.button3) ;
button3.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
changeView(2) ;
}
});
// 코드 계속 ...
}
}
3.3 FrameLayout에 표시될 뷰 변경 코드 작성.
이제 FrameLayout
에 표시될 뷰(View)를 변경하는 기능을 구현합니다. 이를 위해 changeView()라는 함수를 추가한 다음, removeViewAt() 함수와 addView() 함수를 호출하여 뷰(View)를 제거 및 추가합니다.
[STEP-3] "MainActivity.java" - FrameLayout에 표시될 뷰 변경 코드 작성.
public class MainActivity extends AppCompatActivity {
// textView 참조를 저장하기 위한 변수.
TextView textView1 ;
TextView textView2 ;
TextView textView3 ;
// TextView textViews[3] ; // 개선된 코드 (textView 참조를 저장하기 위한 변수.)
@Override
protected void onCreate(Bundle savedInstanceState) {
// ... 코드 계속
// textView에 대한 참조 획득.
textView1 = (TextView) findViewById(R.id.text1) ;
textView2 = (TextView) findViewById(R.id.text2) ;
textView3 = (TextView) findViewById(R.id.text3) ;
/* // 개선된 코드 (textView에 대한 참조 획득.)
textViews[0] = (TextView) findViewById(R.id.text1) ;
textViews[1] = (TextView) findViewById(R.id.text2) ;
textViews[2] = (TextView) findViewById(R.id.text3) ;
*/
// 코드 계속 ...
}
private void changeView(int index) {
FrameLayout frame = (FrameLayout) findViewById(R.id.frame) ;
// 0 번째 뷰 제거. (뷰가 하나이므로, 0 번째 뷰를 제거하면 모든 뷰가 제거됨.)
frame.removeViewAt(0) ;
// index에 해당하는 textView 표시
switch (index) {
case 0 :
frame.addView(textView1) ;
break ;
case 1 :
frame.addView(textView2) ;
break ;
case 2 :
frame.addView(textView3) ;
break ;
}
/* // 개선된 코드 (index에 해당하는 textView 표시.)
if (index < 3) {
frame.addView(textViews[index]) ;
} else {
// TODO : index error.
}
*/
}
}
3.4 FrameLayout의 초기 상태 결정.
마지막으로, 앱 시작 시 FrameLayout
에 표시될 뷰(View)를 결정하기 위해 textView2와 textView3는 removeView() 함수로 제거합니다.
[STEP-4] "MainActivity.java" - onCreate() 함수에서 화면에 표시될 뷰를 제외한 모든 뷰 제거.
public class MainActivity extends AppCompatActivity {
// ... 코드 계속
@Override
protected void onCreate(Bundle savedInstanceState) {
// ... 코드 계속
FrameLayout frame = (FrameLayout) findViewById(R.id.frame) ;
// textView1을 제외한 모든 뷰 제거.
// frame.removeView(textView1) ;
frame.removeView(textView2) ;
frame.removeView(textView3) ;
/* // 개선된 코드 (textView1을 제외한 모든 뷰 제거.)
frame.removeAllViews() ;
frame.addView(textView1) ;
*/
}
}
4. 예제 실행 화면
예제 작성을 완료하고 실행하면 아래와 같은 화면이 표시됩니다.
그리고 버튼을 클릭하면, 클릭된 버튼의 순서에 따른 TextView가 FrameLayout
에 번갈아 표시됩니다.
5. 참고.
- 개발자 레시피 - 프레임레이아웃(FrameLayout)
- [안드로이드 프레임레이아웃(Android FrameLayout)]을 참고하세요.
- FrameLayout에 대한 자세한 도움말.
- [안드로이드 개발 참조문서 FrameLayout]을 참고하세요.
- 개발자 레시피 - 레이아웃 관련 항목
- [안드로이드 레이아웃 (Android Layout)]을 참고하세요.
- [안드로이드 레이아웃 공통사항 (Android Layout Common)]을 참고하세요.
- [안드로이드 리니어레이아웃 (Android LinearLayout)]을 참고하세요.
- [안드로이드 렐러티브레이아웃 (Android RelativeLayout)]을 참고하세요.
- 레이아웃에 대한 자세한 도움말.
- [안드로이드 개발 참조문서 레이아웃 항목]을 참고하세요.
.END.