解決切換Fragment的黑色閃屏問題

Gavin_Mirror發表於2014-11-24

轉載請註明出處:http://blog.csdn.net/jiguangcanhen?viewmode=list

-----------------------------------------------------------------------------------------------------------

問題情景:

在Activity中切入Fragment,在Fragment中顯示了Unity3D的view(對於地圖的View應該是一個效果),在Activity中切換Fragment的時候,會出現黑色閃屏。切換方式使用的是replace方法。

原因:

因為u3d初始化和銷燬的時候,資源比較多,所以耗費時間過長,所以會出現黑色閃屏,而replace方法恰恰是add和remove方法的結合,就會每次初始化和銷燬。

解決辦法:

不用replace方法來做,也就是說,只初始化一次,那麼就是使用add之後利用hide和show方法來完成fragment的切換,這樣的話,就解決的黑色閃屏的問題。

關鍵程式碼:

public void changeFragment(int flag){
		FragmentTransaction ft = fm.beginTransaction();
		Fragment fragment = fm.findFragmentByTag(flag+"");
		boolean isShowOrAdd = true;//true表示show,false表示add
		if(fragment == null){
			isShowOrAdd = false;
			switch(FragmentTags.values()[flag]){
				case u3dFragment:
					fragment = new U3dFragment();
					break;
				case functionFragment:
					fragment = new FunctionFragment();
					break;
				case personalFragment:
					fragment = new PersonalFragment();
					break;
				case cameraAddPeopleFragment:
					fragment = new AddNewPeopleFragment();
					break;
				default:
					break;
			}
		}
		if(currentFragment != null){
			ft.hide(currentFragment);
		}
		if(isShowOrAdd){
			ft.show(fragment);
			fragment.onResume();
		}else{
			ft.add(R.id.contentContainer, fragment, flag+"");
		}
		currentFragment = fragment;
		ft.commit();
	}

根據上面的方式,是可以解決fragment閃屏的問題,可以說,只是避開了,並不是真正解決了。

擴充套件:

問題:

因為我們沒有remove方法,那麼很簡單的明白,我們activity的fragmentlist是一直在增加的,可能就是AFragment,BFragment,BFragment。

在activity切換到其他的activity之後(切換的時候activity顯示的為AFragment),它們的生命週期行走的流程為:
 onResume(activity)->onResume(AFragment)->onResume(BFragment)->onResume(BFragment)
可見,雖然,BFragment和CFragment沒有顯示,處於hide的狀態,但是返回之後,還是會呼叫它們的onResume方法。

進一步引發問題:

因為我的titlebar是在MainActivity中進行的佈局,在Fragment的onResume方法中進行的樣式設定,那麼如果是這種執行順序,那麼titlebar的樣式肯定會出現錯亂。


解決:

對於沒有顯示的方法,在activity執行onPause方法的時候進行remove,也就是下面方法的作用。從而可以解決放這個問題。

private void removeNeedFragment(){
		List<Fragment> list = fm.getFragments();
		System.out.println(list.size()+list.toString());
		if(currentFragment instanceof U3dFragment){
			for(int i = 0 ; i <= list.size() - 1; i++){
				Fragment fragment = list.get(i);
				if(fragment instanceof PersonalFragment 
						|| fragment instanceof FunctionFragment
						|| fragment instanceof AddNewPeopleFragment){
					FragmentTransaction ft = fm.beginTransaction();
					ft.remove(fragment);
					ft.commit();
				}
			}
		}else if(currentFragment instanceof PersonalFragment){
			for(int i = 0 ; i <= list.size() - 1; i++){
				Fragment fragment = list.get(i);
				if(fragment instanceof FunctionFragment
						|| fragment instanceof AddNewPeopleFragment){
					FragmentTransaction ft = fm.beginTransaction();
					ft.remove(fragment);
					ft.commit();
				}
			}
		}
	}
ps:

假設在remove了BFragment之後,堆疊情況如下:

AFragment,null,CFragment,它用null來繼續了代替,size還是3。

並不是我們一般理解的:

AFragment,CFragment,然後size為2


相關文章