Activity内嵌Fragment,当Activity recreate时Fragment被添加多次,造成相互遮盖
問題描述:由于某些原因(如旋轉屏幕,或內存不足時)造成Activity被destroy ,當再次回到該Activity時,系統會recreate 該Activity ,?if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. 如果在該Activity的onCreate中存在add Fragment的代碼(未區分是create 還是recreate activity),則會再次add一次該Fragment,造成該Activity中會內嵌多個相同的Fragment. 所以最終原因還是由于Activity的生命周期造成的。
Recreating an Activity
There are a few scenarios in which your activity is destroyed due to normal app behavior, such as when the user presses the?Back?button or your activity signals its own destruction by calling?finish(). The system may also destroy your activity if it's currently stopped and hasn't been used in a long time or the system needs to free up resources and must shut down cached processes to recover memory.
When your activity is destroyed because the user presses?Back?or the activity finishes itself, all traces of the?Activity?instance is gone forever. However, if the system destroys the activity due to system constraints (rather than normal app behavior), then although the actual?Activity?instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed.The saved data that the system uses to restore the previous state is called the "instance state" and is a collection of key-value pairs stored in a?Bundle?object.
Caution:?Your activity will be destroyed and recreated each time the device configuration changes, like when the user rotates the screen.When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout).
By default, the system uses the?Bundle?instance state to save information about each?View?object in your activity layout (such as the text value entered into an?EditText?object). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more transient state information that you'd like to restore, such as member variables that track the user's progress in the activity.
Note:?In order for the Android system to restore the state of the views in your activity,?each view must have a unique ID, supplied by the?android:id?attribute.
解決方案1:在add Fragment時,區分一下create 狀態和recreate 狀態
public class MainActivity extends FragmentActivity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.news_articles);// Check that the activity is using the layout version with// the fragment_container FrameLayoutif (findViewById(R.id.fragment_container) != null) {// However, if we're being restored from a previous state,// then we don't need to do anything and should return or else// we could end up with overlapping fragments.if (savedInstanceState != null) {return;}// Create a new Fragment to be placed in the activity layoutHeadlinesFragment firstFragment = new HeadlinesFragment();// In case this activity was started with special instructions from an// Intent, pass the Intent's extras to the fragment as argumentsfirstFragment.setArguments(getIntent().getExtras());// Add the fragment to the 'fragment_container' FrameLayoutgetSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();}} }請詳細看下如下注釋: // However, if we're being restored from a previous state,// then we don't need to do anything and should return or else// we could end up with overlapping fragments.
解決方案2:在add Fragment時給該Fragment添加一個Tag,在onCreate中addFragment時給該Fragment增加一個Tag.在onCreate方法中添加Fragment,先findFragmentByTag,如果存在則不用添加該Fragment,如果不存在該Fragment,則添加一個。
總結
以上是生活随笔為你收集整理的Activity内嵌Fragment,当Activity recreate时Fragment被添加多次,造成相互遮盖的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Custom View
- 下一篇: Activity configChang