【问题标题】:android: how do I check if dialogfragment is showingandroid:如何检查是否显示对话框片段
【发布时间】:2014-01-25 15:40:19
【问题描述】:

我使用

启动我的对话框片段
FragmentTransaction ft = 
getFragmentManager().beginTransaction();
MyDialogFragment dialog = new MyDialogFragment()
dialog.show(ft, "dialog");

然后我会处理它

Fragment prev = getFragmentManager().findFragmentByTag("dialog");

但是一旦我收到prev,我如何检查它是否正在显示?

背景故事

我的问题是我的循环代码不断地一次又一次地启动对话框。但如果对话框已经显示,我不希望它再次启动。 这个背景故事只是为了上下文。我寻求的答案不是:“将其移出循环。”

【问题讨论】:

标签: android android-layout android-fragments android-dialogfragment


【解决方案1】:
 if (dialogFragment != null
     && dialogFragment.getDialog() != null
     && dialogFragment.getDialog().isShowing()
     && !dialogFragment.isRemoving()) {
            //dialog is showing so do something 
 } else {
     //dialog is not showing
 }

更新:团队您是否也可以尝试以下调用,我认为它会合乎逻辑地工作:

dialogFragment.isResumed

如果我没记错的话,这应该意味着它在前台显示。

【讨论】:

  • 太棒了!工作! dialog.isVisible() 是真正的罪魁祸首,即使对话框可见,有时也会说false!所以,dialogFragment.getDialog().isShowing() 工作......就像一个魅力!
  • 这按预期工作,应该是公认的答案,但放在最后......
  • 如果 dialogFragment 恰好为空,dialogFragment.getDialog() 将给出空指针异常。
  • 如果你在一瞬间多次调用DialogFragment的创建,dialogFragment = getSupportFragmentManager().findFragmentByTag("dialog");会返回null,所有的对话框都会显示出来。
  • 如果dialogFragment.isRemoving() == false也被添加到这个检查中会有帮助吗?
【解决方案2】:

我将此添加到我的自定义对话框片段中,因此我不必担心外部的任何逻辑。使用 boolean shown 字段覆盖 show()onDismiss() 方法:

  private static boolean shown = false;

    @Override
    public void show(FragmentManager manager, String tag) {
        if (shown) return;

        super.show(manager, tag);
        shown = true;
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        shown = false;
        super.onDismiss(dialog);
    }

如果你想检查它是否显示,你可以为shown boolean 创建一个getter。

【讨论】:

  • 不是最佳答案,如果用户在对话框显示时收到呼叫,对话框将添加两次,因为变量show 将再次创建值false,您必须使show 变量@987654330 @, private static boolean shown = false;
  • +1 表示先前的评论,并且:如果您从外部为每个对话框调用创建一个新实例,则此方法不适用。有人可能会争辩说您可以将“显示”设为静态,但我认为这会产生其他影响
  • stackoverflow.com/a/51934699/2914140:在void show(…)换行:if (shown || manager.isStateSaved()) return;
【解决方案3】:

只需检查它是否为空

if(prev == null)
    //There is no active fragment with tag "dialog"
else
    //There is an active fragment with tag "dialog" and "prev" variable holds a reference to it.

或者,您可以检查片段prev 当前关联的活动,但是,请确保您要求之后确认它不为空,否则您将收到 NullPointerException。像这样:

if(prev == null)
    //There is no active fragment with tag "dialog"
else
    if(prev.getActivity() != this) //additional check
        //There is a fragment with tag "dialog", but it is not active (shown) which means it was found on device's back stack.
    else
        //There is an active fragment with tag "dialog"

【讨论】:

  • 这并不总是有效,例如,如果对话框刚刚被关闭。当我有时想在关闭对话框后立即显示一个对话框时遇到了这个问题(我重用了相同的片段来显示一个“不同的”对话框)。我发现有效的解决方案与下面的@j2emanue 相同。 if (fragment.getDialog() == null || !fragment.getDialog().isShowing()) { fragment.show(fragmentManager, tag); }(就我而言,我已经知道我的片段不为空)。
【解决方案4】:

100% 正常运行时间


class ProgressDialogFragment : DialogFragment() {

 companion object {
    private val TAG = this::class.simpleName
 }

 lateinit var dialogFragmentManager: FragmentManager
 
 fun showDialog() {
    dialogFragmentManager.apply {
       if (findFragmentByTag(TAG) == null) show(this, TAG) else return
    }
 }

}

lateinit var progressDialog: ProgressDialogFragment

初始化:?


class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
   
    initProgressDialog(supportFragmentManager)
}

fun initProgressDialog(fragmentManager: FragmentManager){
    progressDialog = ProgressDialogFragment().apply {
        dialogFragmentManager = fragmentManager
    }
}

在任何地方使用 { progressDialog.showDialog() } ?


附言。 Vel_daN:爱​​你所做的事情?。

【讨论】:

  • 这会让你“很棒”的发现令人失望,但只需连续两次调用progressDialog.showDialog(),你就会得到两个对话框。因为show 是异步的,在系统实际添加对话框之前,您的findFragmentByTag(TAG) == null 检查将为真。
【解决方案5】:

Kotlin 风格:

private fun showDialog(dialogFragment: DialogFragment, tag: String) {
    supportFragmentManager.findFragmentByTag(tag).let { fragment ->
        fragment ?: let {
            supportFragmentManager.beginTransaction().let { transition ->
                dialogFragment.show(transition, tag)
            }
        }
    }
}

【讨论】:

  • 对不起,这个问题甚至没有从技术上解决,所以没有必要卡在你的 Kotlin“解决方案”中
猜你喜欢
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2012-11-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
相关资源
最近更新 更多