하루에 0.01%라도 성장하자

Develop/Android

Fragment 변경시 발생할 수 있는 에러. Error msg : java.lang.IllegalStateException: commit already called

뚠님 2019. 11. 21. 13:34
반응형

이번에 업데이트 중인 앱의 UI를 변경하다가 BottomNavigationView를 사용할 일이 생겼다.

 

BottomNavigationView를 사용하면 하단에 Tab이 있고, MainView에 Fragment가 들어가는데 Tab의 메뉴를 누르면 화면이 변경되어야 한다.

 

앱 구조

위에 이해를 돕기위해 내가 개발한 앱의 레이아웃 구조를 구현했다.

 

FrameLayout 위에 BottomNavigationView , FrameLayout을 그리고 FrameLayout 위에 Fragment를 배치하도록 하였다.

( 기본적인 NavigationView 그리기다.. )

 

Menu1, Menu2, Menu3을 누르면 각각의 Fragment를 그려주는 기능이다.

 

잠깐 코드를 보자.

 

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                switch (item.getItemId()) {
                    case R.id.menu_1: {
                        transaction.replace(R.id.fragment_layout, Menu1Fragment).commitAllowingStateLoss();
                        break;
                    }
                    case R.id.menu_2: {
                        transaction.replace(R.id.fragment_layout, Menu2Fragment).commitAllowingStateLoss();
                        break;
                    }
                    case R.id.menu_3: {
                        transaction.replace(R.id.fragment_layout, Menu3Fragment).commitAllowingStateLoss();
                        break;
                    }
                }
                return true;
            }
        });

 

코드를 보면 BottomNavigationView에 onNavigationItemSelectedListener를 설정해 주고, 클릭하여 아이템이 선택될 때 마다 그에 맞는 Fragment를 보여주는데 오늘 여기서 주목할 것은 아래 코드다.

 

FragmentTransaction transaction = fragmentManager.beginTransaction();

 

지금 현재 이 코드는 onNavigationItemSelectedListener 안에, 즉 아이템이 선택될 때 마다 실행된다.

 

위 코드가 만약 onNavigationItemSelectedListener 밖에 있어서 화면이 사용자에게 보여진 후 1회만 실행 된다면, 한번의 Fragment의 변화를 Commit()한 후 다시 다른 화면으로 Commit하려할 때 아래와 같은 에러가 발생한다.

 

Error msg : java.lang.IllegalStateException: commit already called

 

이미 화면을 그리면서 Commit()한 transaction에 다른 Fragment를 할당하고 Commit()하려 했기 때문에 이미 commit되었다고 에러가 발생하면서 앱이 꺼지는 것이다.

 

따라서 onNavigationItemSelectedListener 안에 작성하여 Item을 선택할 때 마다 transaction을 따로 만들어 주어 관리하는 것이다.

 

 

[ 참고 URL ]

 

참조: http://stackoverflow.com/questions/24561874/android-fragmenttransaction-commit-already-called

 

반응형