片段在方向改变时多次加载
Fragment loads multiple times on orientation change
当我更改模拟器上的方向或 Phone 片段会额外加载一次。如果我将设备旋转 3 次,片段将在最后一次旋转后加载 3 次,如果我将设备旋转 5 次,它将在最后一次旋转后加载 5 次。
主要Activity
...
FragmentOne fragment = new FragmentOne();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.main_container, fragmnet);
transaction.commit();
我在片段中唯一拥有的是日志,没有任何东西会导致片段加载多次。
片段一
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.d(TAG, "onCreateView: ");
return inflater.inflate(R.layout.fragment_fragment_one, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onViewCreated: ");
}
这是旋转一圈后的日志副本,注意 onCreateView 被多次调用,一次方向改变。
2020-04-13 01:23:07.396 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.396 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.418 10857-10857/com.example.myapplication D/MYMainActivity: onCreate:
2020-04-13 01:23:07.423 10857-10857/com.example.myapplication D/MYFragmentOne: onCreateView:
2020-04-13 01:23:07.429 10857-10857/com.example.myapplication D/MYFragmentOne: onViewCreated:
2020-04-13 01:23:07.429 10857-10857/com.example.myapplication D/MYFragmentOne: onCreateView:
2020-04-13 01:23:07.431 10857-10857/com.example.myapplication D/MYFragmentOne: onViewCreated:
2020-04-13 01:23:07.431 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.431 10857-10857/com.example.myapplication D/MYFragmentOne: onCreateView:
2020-04-13 01:23:07.433 10857-10857/com.example.myapplication D/MYFragmentOne: onViewCreated:
App details
compileSdkVersion 29
buildToolsVersion "29.0.2"
applicationId "com.example.myapplication"
minSdkVersion 29
targetSdkVersion 29
什么会导致片段在方向改变的情况下加载这么多次?
这是我的 github link
Link
发生这种情况是因为这是 android 生命周期的 "normal" 行为。当您转身 phone/screen 时,会执行方向更改,其结果是 activity 的重新创建。有一些解决方案:第一个是在清单文件中禁用方向,但这可能不是您正在寻找的解决方案!第二个是检查片段是否已经添加。你可以做这样的事情:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MYMainActivity";
private FragmentOne fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: ");
if (fragment == null) {
fragment = new FragmentOne();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.main_container, fragment);
transaction.commit();
}
}
}
在这种情况下,您不会在每次重新创建 activity 时都添加多个片段。更好的是,您可以从片段管理器中检查片段是否已从 TAG 添加,只需在 transaction.add 函数中添加 id 并检查它是否存在!
希望对您有所帮助。但无论如何,必须阅读 android 生命周期如何为 activity/fragments 工作。
干杯
当 activity 方向改变时,它会再次调用 onCreate()
并且您放入其中的片段也将被重新创建。在这种情况下,您应该仅在 activity 的第一次加载时创建片段。然后在下一次加载时获取保存的片段实例。使用 tag
作为 Fragment
键。
private static final String FRAGMENT_TAG = "fragmentOne";
private Fragment fragment;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
// savedInstanceState always null on activity's first load
if (savedInstanceState == null) {
fragment = new FragmentOne();
} else {
fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_container, fragment, FRAGMENT_TAG)
.commit();
}
当我更改模拟器上的方向或 Phone 片段会额外加载一次。如果我将设备旋转 3 次,片段将在最后一次旋转后加载 3 次,如果我将设备旋转 5 次,它将在最后一次旋转后加载 5 次。
主要Activity
...
FragmentOne fragment = new FragmentOne();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.main_container, fragmnet);
transaction.commit();
我在片段中唯一拥有的是日志,没有任何东西会导致片段加载多次。 片段一
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.d(TAG, "onCreateView: ");
return inflater.inflate(R.layout.fragment_fragment_one, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onViewCreated: ");
}
这是旋转一圈后的日志副本,注意 onCreateView 被多次调用,一次方向改变。
2020-04-13 01:23:07.396 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.396 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.418 10857-10857/com.example.myapplication D/MYMainActivity: onCreate:
2020-04-13 01:23:07.423 10857-10857/com.example.myapplication D/MYFragmentOne: onCreateView:
2020-04-13 01:23:07.429 10857-10857/com.example.myapplication D/MYFragmentOne: onViewCreated:
2020-04-13 01:23:07.429 10857-10857/com.example.myapplication D/MYFragmentOne: onCreateView:
2020-04-13 01:23:07.431 10857-10857/com.example.myapplication D/MYFragmentOne: onViewCreated:
2020-04-13 01:23:07.431 10857-10857/com.example.myapplication D/MYFragmentOne: onCreate:
2020-04-13 01:23:07.431 10857-10857/com.example.myapplication D/MYFragmentOne: onCreateView:
2020-04-13 01:23:07.433 10857-10857/com.example.myapplication D/MYFragmentOne: onViewCreated:
App details
compileSdkVersion 29
buildToolsVersion "29.0.2"
applicationId "com.example.myapplication"
minSdkVersion 29
targetSdkVersion 29
什么会导致片段在方向改变的情况下加载这么多次?
这是我的 github link Link
发生这种情况是因为这是 android 生命周期的 "normal" 行为。当您转身 phone/screen 时,会执行方向更改,其结果是 activity 的重新创建。有一些解决方案:第一个是在清单文件中禁用方向,但这可能不是您正在寻找的解决方案!第二个是检查片段是否已经添加。你可以做这样的事情:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MYMainActivity";
private FragmentOne fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: ");
if (fragment == null) {
fragment = new FragmentOne();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.main_container, fragment);
transaction.commit();
}
}
}
在这种情况下,您不会在每次重新创建 activity 时都添加多个片段。更好的是,您可以从片段管理器中检查片段是否已从 TAG 添加,只需在 transaction.add 函数中添加 id 并检查它是否存在!
希望对您有所帮助。但无论如何,必须阅读 android 生命周期如何为 activity/fragments 工作。 干杯
当 activity 方向改变时,它会再次调用 onCreate()
并且您放入其中的片段也将被重新创建。在这种情况下,您应该仅在 activity 的第一次加载时创建片段。然后在下一次加载时获取保存的片段实例。使用 tag
作为 Fragment
键。
private static final String FRAGMENT_TAG = "fragmentOne";
private Fragment fragment;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
// savedInstanceState always null on activity's first load
if (savedInstanceState == null) {
fragment = new FragmentOne();
} else {
fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_container, fragment, FRAGMENT_TAG)
.commit();
}