问题引入
FirstFragment
public class FirstFragment extends Fragment {
private static final String TAG = "FirstFragment";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG,"FirstFragment----------onCreate");
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG,"FirstFragment----------onCreateView");
return inflater.inflate(R.layout.fragemnfragment_1, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG,"FirstFragment----------onActivityCreate");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onAttach(Activity activity) {
Log.d(TAG,"FirstFragment----------onAttach");
super.onAttach(activity);
}
@Override
public void onStart() {
Log.d(TAG,"FirstFragment----------onStart");
super.onStart();
}
@Override
public void onStop() {
Log.d(TAG,"FirstFragment----------onStop");
super.onStop();
}
@Override
public void onResume() {
Log.d(TAG,"FirstFragment----------onResume");
super.onResume();
}
@Override
public void onPause() {
Log.d(TAG,"FirstFragment----------onPause");
super.onPause();
}
@Override
public void onDetach() {
Log.d(TAG,"FirstFragment----------onDetach");
super.onDetach();
}
@Override
public void onDestroyView() {
Log.d(TAG,"FirstFragment----------onDestroyView");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.d(TAG,"FirstFragment----------onDestroy");
super.onDestroy();
}
}
SecondFragment
public class SecondFragment extends Fragment {
private static final String TAG = "SecondFrgment";
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "SecondFrgment----------onCreateView");
return inflater.inflate(R.layout.fragemnfragment_2, container, false);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "SecondFrgment----------onCreate");
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG,"SecondFrgment----------onActivityCreate");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onAttach(Activity activity) {
Log.d(TAG,"SecondFrgment----------onAttach");
super.onAttach(activity);
}
@Override
public void onStart() {
Log.d(TAG,"SecondFrgment----------onStart");
super.onStart();
}
@Override
public void onStop() {
Log.d(TAG,"SecondFrgment----------onStop");
super.onStop();
}
@Override
public void onResume() {
Log.d(TAG,"SecondFrgment----------onResume");
super.onResume();
}
@Override
public void onPause() {
Log.d(TAG,"SecondFrgment----------onPause");
super.onPause();
}
@Override
public void onDetach() {
Log.d(TAG,"SecondFrgment----------onDetach");
super.onDetach();
}
@Override
public void onDestroyView() {
Log.d(TAG,"SecondFrgment----------onDestroyView");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.d(TAG,"SecondFrgment----------onDestroy");
super.onDestroy();
}
}
Fragment 的xml布局文件
很简单都是一个TextView显示文本内容
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text2"
android:text="千金难买今日醉"
android:textSize="32sp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Activity 代码:
public class FragActivity extends AppCompatActivity {
private static final String TAG = "FragActivity";
private FirstFragment fragment1;
private SecondFragment fragment2;
private RadioGroup mRadioGroup;
private FragmentTransaction transaction;
private int mPosition = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragemtn);
mRadioGroup = (RadioGroup) findViewById(R.id.radio_group);
Log.d(TAG, "Activity---------onCreate");
mRadioGroup.check(R.id.my_history);
setFragment(mPosition);
mRadioGroup.setOnCheckedChangeListener(checkedListener);
// mRadioGroup.check(R.id.my_history);//设置默认值,放在监听后面,会导致fragment1加载两次
}
private RadioGroup.OnCheckedChangeListener checkedListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.my_history:
mPosition = 0;
break;
case R.id.subordinate_history:
mPosition = 1;
break;
default:
break;
}
setFragment(mPosition);
}
};
private void setFragment(int position) {
transaction = getSupportFragmentManager().beginTransaction();
hideAllFragments(transaction);
switch (position) {
case 0:
fragment1 = (FirstFragment) getSupportFragmentManager().findFragmentByTag("first");
if (fragment1 == null) {
fragment1 = new FirstFragment();
transaction.add(R.id.container, fragment1, "first");
} else {
transaction.show(fragment1);
}
break;
case 1:
fragment2 = (SecondFragment) getSupportFragmentManager().findFragmentByTag("second");
if (fragment2 == null) {
fragment2 = new SecondFragment();
transaction.add(R.id.container, fragment2, "second");
} else {
transaction.show(fragment2);
}
break;
default:
break;
}
transaction.commit();
}
/**
* 隐藏所有fragment
*
* @param transaction
*/
private void hideAllFragments(FragmentTransaction transaction) {
if (fragment1 != null) {
transaction.hide(fragment1);
}
if (fragment2 != null) {
transaction.hide(fragment2);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Activity...onDestroy");
}
Activity xml布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="125dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:background="@drawable/history_tab_bg"
android:gravity="center_vertical"
android:orientation="horizontal">
<RadioButton
android:id="@+id/my_history"
style="@style/HistoryAgentRadioButtonStyle"
android:text="A"/>
<RadioButton
android:id="@+id/subordinate_history"
style="@style/HistoryAgentRadioButtonStyle"
android:text="B"/>
</RadioGroup>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Style xml文件:
<style name="HistoryAgentRadioButtonStyle">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">30dp</item>
<item name="android:layout_weight">1</item>
<item name="android:button">@null</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/history_agent_color_selector</item>
<item name="android:background">@drawable/history_agent_selector</item>
<item name="android:gravity">center</item>
</style>
运行结果:
旋转屏幕使得Activity重走生命周期方法,出现下面情况:
出现UI重叠的原因:
虽然切换屏幕时, Fragment会onDettach,但是Activity中还保存着Fragment的引用, 在ActivityonDestroy之前,会调用onSaveInstance()保存视图层(View Hierarchy),所以当Activity通过导航再次被重建时,之前被实例化过的Fragment依然会出现在Activity中.
onSaveInstanceState()在转跳到其他Activity、打开多任务窗口、使用Home回到主屏幕这些操作中会被调用, google文档说:This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state.
解决方案:
Activity中:
@Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
}
运行结果(生命周期):
进入界面选中FirstFragment时:
切换到SecondFragment时:
再切换到FirstFragment时:
没有出现任何日志,说明FirstFragment并没有重走生命周期方法, 这也就是使用add+hide+show方式时,切换Fragment是不会重走生命周期方法.
旋转屏幕: