我的问题涉及一个包含三个支持片段的活动。其中一个是普通编程片段(我们称之为主页片段)。当设备方向发生变化时,另一个是添加在主页片段上面的纵向片段,还有一个是“无头”的片段,可以继续异步任务而不受配置更改的影响。非常简单,我是根据这个很好的示例进行工作的。
public class HeadlessCustomerDetailFetchFragment extends Fragment{
private RequestCustomerDetails mRequest;
private AsyncFetchCustomerDetails mAsyncFetchCustomerDetails;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
mRequest = (RequestCustomerDetails)getActivity();
}
public void startFetching(String scannedBarcode) {
if(mAsyncFetchCustomerDetails != null && mAsyncFetchCustomerDetails.getStatus() == AsyncTask.Status.RUNNING) return;
if(mAsyncFetchCustomerDetails == null || mAsyncFetchCustomerDetails.getStatus() == AsyncTask.Status.FINISHED)
mAsyncFetchCustomerDetails = new AsyncFetchCustomerDetails(getActivity(), mRequest, mPartner, scannedBarcode);
}
public void stopFetching() {
if(mAsyncFetchCustomerDetails != null && mAsyncFetchCustomerDetails.getStatus() != AsyncTask.Status.RUNNING) return;
mAsyncFetchCustomerDetails.cancel(true);
}
在我的活动的onCreate()方法中,如果必要的话,我会创建并添加无界面碎片。
mHeadlessCustomerDetailFetchFragment = (HeadlessCustomerDetailFetchFragment)getSupportFragmentManager()
.findFragmentByTag(HeadlessCustomerDetailFetchFragment.class.getSimpleName());
if(mHeadlessCustomerDetailFetchFragment == null) {
mHeadlessCustomerDetailFetchFragment = HeadlessCustomerDetailFetchFragment.instantiate(this, HeadlessCustomerDetailFetchFragment.class.getName());
getSupportFragmentManager().beginTransaction()
.add(mHeadlessCustomerDetailFetchFragment, mHeadlessCustomerDetailFetchFragment.getClass().getSimpleName())
.commit();
getSupportFragmentManager().executePendingTransactions();
id = null;
}
然后我会在创建视图的时候,通过我的startFetching()函数,在延迟6秒后(用于测试)启动一个异步任务。这个视图碎片被添加到当屏幕方向变为纵向时。屏幕方向的改变是在活动的onCreate()中检测到的。
if (savedInstanceState == null) {
// Do some initial stuff for the home fragment
}
else {
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//Launch portrait fragment
FragmentLauncher.launchPortraitFragment(this);
}
任务完成后,我返回到活动并尝试更新活动肖像片段的UI,但是片段管理器找不到它,findFragmentByTag() 返回 null。
明确一下:
- 标记是正确的。
- 如果我在设备未发生方向变化时(比如在活动的 onResume() 中)在其他地方启动异步任务,则可以找到该片段。
- 如果我不要求无头片段保留自己-从而失去不重新创建它的好处,则可以正确找到纵向片段。
- 调试时,如果无头片段没有被保留,我可以在管理器中看到所有3个片段。如果保留它,则我只能看到无头片段。
setRetained
会改变popBackStackImmediate(name, flags)
的工作方式?我可以尝试删除或修改getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
。 - Leo Landau