달달한 스토리

728x90
반응형

 

이번주의 마무리가 되었다.

 

벌써 금요일이다. 개발을 하면서 하루하루 시간이 정말 빨리 가는 것 같은 느낌이다.

 

오늘은 만들고 있던 앱이 프래그먼트에서 프래그먼트로 이동할 때,

 

값이 초기화 되고 있다는 사실을 깨달았다.

 

값을 주고 

 

프래그먼트 생명주기에 하나씩 값을 주면서

 

연구해 보았지만,

 

onAttach가 제일 먼저 생성이 됨에도,

 

초기화를 막을 방법이 없다는 사실을 깨달았다.

 

그래도 포기하지 않고, 액티비티의 생명주기에도 손을 댔는데,

 

프래그먼트가 이상하게 먼저 생성이 되어서

 

액티비티에 값이 전달이 되질 않았다.

 

물론 번들로 하였다.

 

하지만, 볼리를 이용한 작업이 내 생각처럼 되질 않았다.

 

그래서 찾아내고 찾아내니

 

프래그먼트를 그냥 재생성 하지 않고,

 

다른 프래그먼트를 왔다갔다 해도

 

그대로 값이 남아있고, 초기화 하지 않는 법이 있었다.

 

약간에 가라를 치는 방법이다.

 


해결법

 

나 같은 경우는 바텀네비게이션 뷰를 이용하였는데,

 

코드는 아래와 같다.

 

public class BottomNavi extends AppCompatActivity {

	private BottomNavigationView bottomNavigationView;
    private HomeMain fragment1; //프래그먼트

		@Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bottom_navi);
 
 
 bottomNavigationView = findViewById(R.id.nav_view);

            /**제일 처음 띄워주는 프래그먼트*/
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.container, fragment1, "home")
                    .commitAllowingStateLoss();

            /**아이콘 선택시 원하는 프래그먼트가 띄워지게 하기*/ /** 프래그먼트 replace(탭 이동시 새로생성)을 방지하기위해 add와 hide, show를 이용하여, 한 번만 뜨게 만들도록 하였다.*/
            bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    /**각 탭에 아이디의 따라 다르게 띄워주기*/
                    FragmentManager fragmentManager = getSupportFragmentManager();

                    switch (item.getItemId()) {
                        case R.id.home : {
                            if (fragmentManager.findFragmentByTag("home") != null) {
                                //프래그먼트가 존재한다면 보여준다.
                                fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag("home")).commit();
                            } else {
                                //존재하지 않는다면 프래그먼트를 매니저에 추가
                                fragmentManager.beginTransaction().add(R.id.container, new HomeMain(), "home").commit();
                            }
                            if (fragmentManager.findFragmentByTag("health") != null) {
                                //다른프래그먼트가 보이면 가려준다.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("health")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("diary") != null) {
                                //다른프래그먼트가 보이면 가려준다.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("diary")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("settings") != null) {
                                //다른프래그먼트가 보이면 가려준다.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("settings")).commit();
                            }
                            return true;
                        }
                        case R.id.check_health : {

                            if (fragmentManager.findFragmentByTag("health") != null) {
                                //if the fragment exists, show it.
                                fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag("health")).commit();
                            } else {
                                //if the fragment does not exist, add it to fragment manager.
                                fragmentManager.beginTransaction().add(R.id.container, new HealthCheck(), "health").commit();
                            }
                            if (fragmentManager.findFragmentByTag("home") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("home")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("diary") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("diary")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("settings") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("settings")).commit();
                            }
                            return true;
                        }
                        case R.id.diary : {

                            if (fragmentManager.findFragmentByTag("diary") != null) {
                                //if the fragment exists, show it.
                                fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag("diary")).commit();
                            } else {
                                //if the fragment does not exist, add it to fragment manager.
                                fragmentManager.beginTransaction().add(R.id.container, new Diary(), "diary").commit();
                            }
                            if (fragmentManager.findFragmentByTag("home") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("home")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("health") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("health")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("settings") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("settings")).commit();
                            }

                            return true;
                        }
                        case R.id.settings : {

                            if (fragmentManager.findFragmentByTag("settings") != null) {
                                //if the fragment exists, show it.
                                fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag("settings")).commit();
                            } else {
                                //if the fragment does not exist, add it to fragment manager.
                                fragmentManager.beginTransaction().add(R.id.container, new Settings(), "settings").commit();
                            }
                            if (fragmentManager.findFragmentByTag("home") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("home")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("health") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("health")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("diary") != null) {
                                //if the other fragment is visible, hide it.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("diary")).commit();
                            }

                            return true;
                        }

                        default:return false;
                    }
                }
            });
         }

 

프래그먼트 매니저와 프래그먼트에 태그를 넣어서 절묘하게 가리고, 보여주는 코드이다.

 

이렇게 하면, 프래그먼트가 액티비티 위에 최초 한 번 떠 있는 상태로

 

앱을 destroy하지 않는 이상

 

계속 이 상태로 둘 수 있다.

 

코드를 살펴보자.

 

/**제일 처음 띄워주는 프래그먼트*/
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.container, fragment1, "home")
                    .commitAllowingStateLoss();

 

우선 프래그먼트 매니저로 트랜잭션을 해서 제일 처음에 보일 프래그먼트를 만들어준다.

 

home이라는 태그를 달아준다.(이름 상관없음)

 

그 다음은

 

바텀네비게이션에 변수를 선언해 setOnNavigationItemSelectedListener를 해주고,

 

메서드 안에서 프래그먼트 매니저를 한 번더 호출해준다.

 

switch (item.getItemId()) {
                        case R.id.home : {
                            if (fragmentManager.findFragmentByTag("home") != null) {
                                //프래그먼트가 존재한다면 보여준다.
                                fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag("home")).commit();
                            } else {
                                //존재하지 않는다면 프래그먼트를 매니저에 추가
                                fragmentManager.beginTransaction().add(R.id.container, new HomeMain(), "home").commit();
                            }
                            if (fragmentManager.findFragmentByTag("health") != null) {
                                //다른프래그먼트가 보이면 가려준다.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("health")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("diary") != null) {
                                //다른프래그먼트가 보이면 가려준다.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("diary")).commit();
                            }
                            if (fragmentManager.findFragmentByTag("settings") != null) {
                                //다른프래그먼트가 보이면 가려준다.
                                fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag("settings")).commit();
                            }
                            return true;
                        }

 

나 같은 경우는 스위치문으로 작성 하였다.

 

home 프래그먼트 탭을 클릭하였을 때,

 

home이란 태그를 가진 프래그먼트를 보여주는데, 값이 없으면,

 

프래그먼트 매니저에 그 프래그먼트를 추가해준다.

 

그리고 나서

 

다른 프래그먼트가 혹시나 보일 수 있으니,

 

보이게 된다면 가려준다는 코드를 나머지 아래

 

if문으로 적는다.

 

나머지도 똑같다.

 

다른 프래그먼트도 이런 식으로 각자 값을 줘서 적어주면 된다.

 

그렇다면 결과는 이런식으로 될것이다.

 

 

나 같은 경우는 가운데 시간 타이머 쓰레드가 프래그먼트에 들어올때마다

 

실행되게 해놓았는데, 이게 골칫거리인게,

 

갔다오면,

 

돌아가던 타이머 위에 또 시간이 중첩되서 돌아가는 것이였다.

 

다행히 지금 해결했지만,

 

정말 골치아팠다.

 

지금은 위에 코드로 해결한 상태이다.

 

 

 

오늘은 바텀네비게이션 뷰에서 프래그먼트를 부드럽게? 하는 법에 대해 알아보았다.

 

혹시나 값이 초기화 되거나,

 

중첩되지 않게 해야할 상황이 생기면 사용하기 좋은 방법인 것 같다.

 

오늘도 공부 끝!

728x90
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading