首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从onActivityResult显示DialogFragment

从onActivityResult显示DialogFragment
EN

Stack Overflow用户
提问于 2012-04-12 05:33:27
回答 15查看 39K关注 0票数 82

在我的onActivityResult中,我的一个片段有以下代码:

onActivityResult(int requestCode, int resultCode, Intent data){
   //other code
   ProgressFragment progFragment = new ProgressFragment();  
   progFragment.show(getActivity().getSupportFragmentManager(), PROG_DIALOG_TAG);
   // other code
}

但是,我得到了以下错误:

Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState   

有人知道这是怎么回事吗,或者我怎么解决这个问题?我需要注意的是,我使用的是Android支持包。

EN

回答 15

Stack Overflow用户

回答已采纳

发布于 2013-04-04 11:38:35

如果你使用Android支持库,onResume方法不是正确的地方,在那里玩碎片。应该在onResumeFragments方法中完成,参见onResume方法说明:http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html#onResume%28%29

因此,从我的角度来看,正确的代码应该是:

private boolean mShowDialog = false;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
  super.onActivityResult(requestCode, resultCode, data);

  // remember that dialog should be shown
  mShowDialog = true;
}

@Override
protected void onResumeFragments() {
  super.onResumeFragments();

  // play with fragments here
  if (mShowDialog) {
    mShowDialog = false;

    // Show only if is necessary, otherwise FragmentManager will take care
    if (getSupportFragmentManager().findFragmentByTag(PROG_DIALOG_TAG) == null) {
      new ProgressFragment().show(getSupportFragmentManager(), PROG_DIALOG_TAG);
    }
  }
}
票数 76
EN

Stack Overflow用户

发布于 2012-04-12 06:35:04

编辑:不是bug,而是fragments框架中的一个缺陷。这个问题的更好答案是上面@Arcao提供的答案。

-原始帖子

实际上,它是一个带有支持包的known bug (编辑:实际上不是一个bug。参见@alex-lockwood的评论)。在错误报告的注释中发布的解决方法是修改DialogFragment的源代码,如下所示:

public int show(FragmentTransaction transaction, String tag) {
    return show(transaction, tag, false);
}


public int show(FragmentTransaction transaction, String tag, boolean allowStateLoss) {
    transaction.add(this, tag);
    mRemoved = false;
    mBackStackId = allowStateLoss ? transaction.commitAllowingStateLoss() : transaction.commit();
    return mBackStackId;
}

请注意,这是一个巨大的黑客攻击。我实际做的方法是制作我自己的对话片段,我可以从原始片段中注册。当另一个对话框片段做了一些事情(比如被解除)时,它会告诉任何监听器它正在消失。我是这样做的:

public static class PlayerPasswordFragment extends DialogFragment{

 Player toJoin;
 EditText passwordEdit;
 Button okButton;
 PlayerListFragment playerListFragment = null;

 public void onCreate(Bundle icicle){
   super.onCreate(icicle);
   toJoin = Player.unbundle(getArguments());
   Log.d(TAG, "Player id in PasswordFragment: " + toJoin.getId());
 }

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle){
     View v = inflater.inflate(R.layout.player_password, container, false);
     passwordEdit = (EditText)v.findViewById(R.id.player_password_edit);
     okButton = (Button)v.findViewById(R.id.ok_button);
     okButton.setOnClickListener(new View.OnClickListener(){
       public void onClick(View v){
         passwordEntered();
       }
     });
     getDialog().setTitle(R.string.password_required);
     return v;
 }

 public void passwordEntered(){
   //TODO handle if they didn't type anything in
   playerListFragment.joinPlayer(toJoin, passwordEdit.getText().toString());
   dismiss();
 }

 public void registerPasswordEnteredListener(PlayerListFragment playerListFragment){
   this.playerListFragment = playerListFragment;
 }

 public void unregisterPasswordEnteredListener(){
   this.playerListFragment = null;
 }
}

因此,现在我有一种方法可以在发生事情时通知PlayerListFragment。请注意,适当地调用unregisterPasswordEnteredListener非常重要(在上面的例子中,当PlayerListFragment“消失”时),否则当注册的侦听器不再存在时,此对话框片段可能会尝试调用该侦听器上的函数。

票数 27
EN

Stack Overflow用户

发布于 2012-04-12 05:54:36

我相信这是一个Android的bug。基本上,安卓在活动/片段生命周期中的错误位置(在onStart()之前)调用onActivityResult。

该漏洞已在https://issuetracker.google.com/issues/36929762上报告

我基本上通过将意图存储为稍后在onResume()中处理的参数来解决它。

编辑对于这个问题,现在有更好的解决方案,这在2012年是不存在的。请参阅其他答案。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10114324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档