정상에서 IT를 외치다

[Android, fragmentManager] 상태 유지된 fragment 보여주기 본문

안드로이드

[Android, fragmentManager] 상태 유지된 fragment 보여주기

Black-Jin 2018. 10. 12. 16:40
반응형

안녕하세요. 블랙진 입니다.


이번에는 한 화면에 여러개의 프래그먼트를 어떻게 사용하면 좋을 지 포스팅 해보겠습니다.


구조는 MainActivity 1 개와 A ~ C Fragment 가 있고 하단 MOVE A ~ C 를 누르면 해당 Fragment 가 나옵니다.


또한 각 Fragment 에는 LIKE 버튼있습니다. 이를 누르면 숫자가 1씩 오르고 TextView 에 보여줍니다.





package


      



activity_main

<?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"
tools:context=".MainActivity">

<FrameLayout
android:id="@+id/fl_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent">

<Button
android:id="@+id/btn_main_a"
android:text="move A"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button
android:id="@+id/btn_main_b"
android:text="move B"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button
android:id="@+id/btn_main_c"
android:text="move C"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

</android.support.constraint.ConstraintLayout>

fragment_a ~ c

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

<TextView
android:text="A Fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/tv_fragment_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button
android:id="@+id/btn_fragment_a"
android:text="like"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

Fragment A ~ C 의 구조는 모두 같고 위 코드에서 변수명 a 만 b 또는 c 로 변경해서 사용했습니다.

(ex. TextView의 'A Fragment' 를  'B Fragment' 또는 'C Fragment' 로 변경)


Fragment A ~ C

public class A_Fragment extends Fragment {

@BindView(R.id.tv_fragment_a)
TextView tvFragmentA;

private int count = 0;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
ButterKnife.bind(this, view);

return view;
}

@OnClick(R.id.btn_fragment_a) void onClick() {
count++;
String str = "count : " + count;
tvFragmentA.setText(str);
}
}

버튼을 누르면 TextView 에 count 가 1씩 증가 되서 표시됩니다.


MainActivity

public class MainActivity extends AppCompatActivity {

private FragmentManager fragmentManager;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);

fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fl_main, new A_Fragment()).commit();

}

@OnClick(R.id.btn_main_a) void onMoveA() {
fragmentManager.beginTransaction().replace(R.id.fl_main, new A_Fragment()).commit();
}

@OnClick(R.id.btn_main_b) void onMoveB() {
fragmentManager.beginTransaction().replace(R.id.fl_main, new B_Fragment()).commit();
}

@OnClick(R.id.btn_main_c) void onMoveC() {
fragmentManager.beginTransaction().replace(R.id.fl_main, new C_Fragment()).commit();
}

}

짜잔 완성입니다.!!

이렇게 작업한 결과물 입니다.



A ~ B Fragment 화면 전환이 잘 이루어 지고 있습니다. 하지만!!! Like 한 데이터 들이 해당 Fragment 로 돌아왔을 때 유지가 안되는 것을 확인할 수 있습니다.

이는 fragmenManager 에서 replace 를 하게 되면 기존에 있던 fragment 는 삭제 되고 새로운 Fragment 가 생성되기 때문에 기존 데이터가 유지되지 못합니다. 이에 기존에 생성한 Fragment 가 있다면 이를 재사용 할 수 있도록 코드를 수정해 보겠습니다.



Fragment 재사용 코드


MainActivity

public class MainActivity extends AppCompatActivity {

private FragmentManager fragmentManager;

private Fragment fa, fb, fc;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);

fragmentManager = getSupportFragmentManager();

fa = new A_Fragment();
fragmentManager.beginTransaction().replace(R.id.fl_main,fa).commit();

}

@OnClick(R.id.btn_main_a) void onMoveA() {

if(fa == null) {
fa = new A_Fragment();
fragmentManager.beginTransaction().add(R.id.fl_main, fa).commit();
}

if(fa != null) fragmentManager.beginTransaction().show(fa).commit();
if(fb != null) fragmentManager.beginTransaction().hide(fb).commit();
if(fc != null) fragmentManager.beginTransaction().hide(fc).commit();
}

@OnClick(R.id.btn_main_b) void onMoveB() {

if(fb == null) {
fb = new B_Fragment();
fragmentManager.beginTransaction().add(R.id.fl_main, fb).commit();
}

if(fa != null) fragmentManager.beginTransaction().hide(fa).commit();
if(fb != null) fragmentManager.beginTransaction().show(fb).commit();
if(fc != null) fragmentManager.beginTransaction().hide(fc).commit();
}

@OnClick(R.id.btn_main_c) void onMoveC() {

if(fc == null) {
fc = new C_Fragment();
fragmentManager.beginTransaction().add(R.id.fl_main, fc).commit();
}

if(fa != null) fragmentManager.beginTransaction().hide(fa).commit();
if(fb != null) fragmentManager.beginTransaction().hide(fb).commit();
if(fc != null) fragmentManager.beginTransaction().show(fc).commit();
}
}

이렇게 코드를 사용하시면 됩니다.


1. Fragment 변수 fa, fb, fc 를 선언합니다.

2. fragmenManager에 각 Fragment 를 add 해 줍니다.

(add 를 하면 기존의 프래그먼트를 지우지 않고 그 위에 추가해주게 됩니다.)

3. fragmentManger.beginTrasaction() 의 show, hide 함수를 통해 원하는 프래그먼트 화면만 보여줍니다.




A,B,C 화면 으로 이동해도 기존에 생성 했던 Fragment 를 사용하기 때문에 데이터가 모두 그대로인 모습입니다.


참고로 해당 프래그먼트만 지우고 싶은 경우

fragmentManager.beginTransaction().remove(fa).commit();

remove 함수를 사용하시면 됩니다.

반응형
Comments