안드로이드 4.0에서 선보인 Fragment예제를 보다 보면
FragmentManager와 FragmentTransaction을 이용해서 Fragment를 붙이게 되는데
예제를 그대로 따라 하다보면 몇가지 오류를 범하게되었다
버튼 1 | 버튼 2 |
버튼 3 |
|
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnFisrt = (Button)findViewById(R.id.btnFirst);
Button btnSecond = (Button)findViewById(R.id.btnSecond);
Button btnThree = (Button)findViewById(R.id.btnThree);
btnFisrt.setOnClickListener(this);
btnSecond.setOnClickListener(this);
btnThree.setOnClickListener(this);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.frameLayout,mFirstFragment,FRAGMENT_FIRST);
ft.add(R.id.frameLayout,mSecondFragment,FRAGMENT_SECOND);
ft.add(R.id.frameLayout,mThreeFragment,FRAGMENT_THREE);
ft.hide(mFirstFragment);
ft.hide(mSecondFragment);
ft.hide(mThreeFragment);
ft.commit();
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.btnFirst) {
Log.d(CLASSNAME,"onClick R.id.btnFirst");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.show(mFirstFragment);
ft.hide(mSecondFragment);
ft.hide(mThreeFragment);
ft.addToBackStack(null);
ft.commit();
} else if(v.getId()==R.id.btnSecond) {
Log.d(CLASSNAME,"onClick R.id.btnSecond");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.hide(mFirstFragment);
ft.show(mSecondFragment);
ft.hide(mThreeFragment);
ft.addToBackStack(null);
ft.commit();
} else if(v.getId()==R.id.btnThree) {
Log.d(CLASSNAME,"onClick R.id.btnThree");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.hide(mFirstFragment);
ft.hide(mSecondFragment);
ft.show(mThreeFragment);
ft.addToBackStack(null);
ft.commit();
}
}
1 |
2 |
3 | 4 |
1번 클릭 |
2번 클릭 | 3번 클릭 | back key |
시에 아래와 같이 화면이 겹쳐지는 현상이 발생하였다.
1,2번 Fragment가 겹쳐보임
위처럼 1,2번 Fragment가 겹치는 현상이 발생한다.
겹치는 것을 확인하기 위해 FrameLayout을 LinerLayout으로 변경해보았다.
1 |
2 | 3 |
1번 클릭 | 2번 클릭 |
3번 클릭 |
1번 Fragment가 pop 된 상태 2,3번 Fragment가 보임 의도 대로 였으면 아무 것도 보이면 안되었다. | 2번 Fragment가 pop 된 상태 1,3번 Fragment가 보임 의도대로 였으면 1번 Fragment가 보여야 한다. | 2번 Fragment가 pop 된 상태 1,3번 Fragment가 보임 의도 대로 였으면 2번 Fragment가 보여야 한다. |
3번 Back Key>Back Key >Back Key | 3번 Back Key>Back Key | 3번까지 클릭하고 back key를 눌렀을 경우 |
위 처럼 화면이 이상하게 나타난다.
3번 클릭하고 back key를 클릭하면 3번 FragmentTransection이 pop되어 3번 내용이 hide되는 것으로
보이나 1,2번 Fragment내용이 보이는 예상하지 못한 결과를 보였다.
3번 클릭하고 back key>back key 를 클릭하면 2번 FragmentTransection까지 pop이 되면서
2번이 hide되고 1,3번 화면이 보이는 역시 예상하지 못한 결과를 보인다.
3번 클릭하고 back key>back key>back key를 클릭하면 1번 FragmentTransction까지 pop되면서
1번이 hide되고 2,3번 화면이 보이는 역시 예상하지 못한 결과를 보인다.
예상했던 것은 pop 되면 그전 구성한 화면이 표시되는 것을 기대했으나 그렇게 되지 않았다.
안드로이드의 버그로 보인다. show,hide의 이전 상태를 제대로 기억하지 못하는 것 같다.
add되신 replace를 사용하여 구성하여 보았다.
FragmentBackStack_issue_1_fixed.zip
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnFisrt = (Button)findViewById(R.id.btnFirst);
Button btnSecond = (Button)findViewById(R.id.btnSecond);
Button btnThree = (Button)findViewById(R.id.btnThree);
btnFisrt.setOnClickListener(this);
btnSecond.setOnClickListener(this);
btnThree.setOnClickListener(this);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.frameLayout,mFirstFragment,FRAGMENT_FIRST);
ft.commit();
}
최초 onCreate에 add를 하여 첫번째 Fragment가 보이도록 했다.
@Override
public void onClick(View v) {
if(v.getId()==R.id.btnFirst) {
Log.d(CLASSNAME,"onClick R.id.btnFirst");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frameLayout,mFirstFragment,FRAGMENT_FIRST);
ft.addToBackStack(null);
ft.commit();
} else if(v.getId()==R.id.btnSecond) {
Log.d(CLASSNAME,"onClick R.id.btnSecond");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frameLayout,mSecondFragment,FRAGMENT_SECOND);
ft.addToBackStack(null);
ft.commit();
} else if(v.getId()==R.id.btnThree) {
Log.d(CLASSNAME,"onClick R.id.btnThree");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frameLayout,mThreeFragment,FRAGMENT_THREE);
ft.addToBackStack(null);
ft.commit();
}
}
이후 버튼클릭시 replace를 하여 이미 멤버변수로 할당 되어있는 Fragment 객체들로 replace를 시킨다.
1 | 2 | 3 |
1번 클릭 |
2번 클릭 | 3번 클릭 |
1번 Fragment pop 최초 1번 Fragment가 add된 이후 1번 버튼을 클릭하였으므로 1번이 Fragment pop 되어도 1번 Fragment가 보여진다. 정상 동작 | 2번 Fragment pop 1번 Fragment가 보여진다. 정상 동작 | 3번 버튼 까지 클릭하고 back key 시 3번 Fragment pop 2번 Fragment가 보여진다. 정상 동작 |
3번 Back Key>Back Key >Back Key | 3번 Back Key>Back Key | 3번까지 클릭하고 back key를 눌렀을 경우 |
위 처럼 나타나면 해당 동작은 정상동작이다.
위 와 같은 의도로 사용될때 현재 4.12 JB버전 까지는 add,show,hide보다 replace를 이용하는 것이
맞는 것으로 보인다.
'PROGRAMING > Android' 카테고리의 다른 글
Fragment 에서 BackStack 사용안하기. (0) | 2013.03.04 |
---|---|
Fragment에서 BackStack 사용시 현재 전면에 나와있는 Fragment알아오기(OnBackStackChangedListener) (1) | 2013.03.04 |
interface를 이용하여 DialogFragment이벤트의 구현부를 다른 장소에 구현한다. (0) | 2013.03.03 |
DialogFragment(AlertDialog) 안에 ListView 넣기 및 이벤트 받기 확인 (1) | 2013.03.03 |
DialogFragment (0) | 2013.03.03 |