Я использую стороннюю библиотеку, и иногда появляется диалог. Прежде чем завершить текущую работу, я хочу проверить, появилось ли диалоговое окно в текущем контексте.
Есть ли API для этого?
Я использую стороннюю библиотеку, и иногда появляется диалог. Прежде чем завершить текущую работу, я хочу проверить, появилось ли диалоговое окно в текущем контексте.
Есть ли API для этого?
Вы можете проверить, работает ли он над активными фрагментами этого действия и проверяет, является ли один из них DialogFragment, что означает, что на экране есть активное диалоговое окно:
public static boolean hasOpenedDialogs(FragmentActivity activity) {
List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment instanceof DialogFragment) {
return true;
}
}
}
return false;
}
Я столкнулся с аналогичной проблемой и не хотел изменять все местоположения, где создавались и показывались диалоги. Мое решение состояло в том, чтобы посмотреть, был ли просмотр, который я показывал, с помощью hasWindowFocus()
. Это не будет работать во всех ситуациях, но работает в моем конкретном случае (это было для внутреннего приложения записи, используемого в довольно ограниченных обстоятельствах).
Это решение не было тщательно проверено на надежность, но я решил, что я опубликую его, если он поможет кому-то.
AFAIK - для этого нет публичного API.
Рекомендуемый способ состоит в том, чтобы иметь ссылку на диалог и проверять isShowing()
и при необходимости dismiss()
, но поскольку вы используете стороннюю библиотеку, это могут быть не варианты для вас.
Лучше всего проверить документацию для библиотеки, которую вы используете. Если это не поможет, вам не повезло.
Подсказка: активность переключается в состояние "приостановлено", если появляется диалоговое окно. Вы можете "злоупотреблять" этим поведением;)
Это использует отражения и скрытые API для получения активных корней. Если появится диалоговое окно с предупреждением, это приведет к возврату дополнительного корня представления. Но осторожно, так как даже всплывающее окно с тостами вернет дополнительный корень представления.
Я подтвердил совместимость с Android 4.1 до Android 6.0, но, конечно, это может не работать в более ранних версиях Android.
Я не проверял поведение для многооконных режимов.
@SuppressWarnings("unchecked")
public static List<ViewParent> getViewRoots() {
List<ViewParent> viewRoots = new ArrayList<>();
try {
Object windowManager;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
windowManager = Class.forName("android.view.WindowManagerGlobal")
.getMethod("getInstance").invoke(null);
} else {
Field f = Class.forName("android.view.WindowManagerImpl")
.getDeclaredField("sWindowManager");
f.setAccessible(true);
windowManager = f.get(null);
}
Field rootsField = windowManager.getClass().getDeclaredField("mRoots");
rootsField.setAccessible(true);
Field stoppedField = Class.forName("android.view.ViewRootImpl")
.getDeclaredField("mStopped");
stoppedField.setAccessible(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
List<ViewParent> viewParents = (List<ViewParent>) rootsField.get(windowManager);
// Filter out inactive view roots
for (ViewParent viewParent : viewParents) {
boolean stopped = (boolean) stoppedField.get(viewParent);
if (!stopped) {
viewRoots.add(viewParent);
}
}
} else {
ViewParent[] viewParents = (ViewParent[]) rootsField.get(windowManager);
// Filter out inactive view roots
for (ViewParent viewParent : viewParents) {
boolean stopped = (boolean) stoppedField.get(viewParent);
if (!stopped) {
viewRoots.add(viewParent);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return viewRoots;
}
Я предполагаю, что вы имеете дело с сторонней библиотекой, и у вас нет доступа к объекту диалога.
Вы можете получить представление корня из активности,
Затем вы можете использовать алгоритм обхода дерева, чтобы узнать, можете ли вы достигнуть какого-либо детского представления. Вы не должны доходить до какого-либо из ваших дочерних представлений, если отображается окно предупреждения.
Когда отображается представление предупреждения (проверьте с помощью Ui Automator), единственным элементом, присутствующим в дереве пользовательского интерфейса, является DialogBox/DialogActivity. Вы можете использовать этот трюк, чтобы увидеть, отображается ли диалоговое окно на экране. Хотя это звучит дорого, его можно оптимизировать.
Вы можете переопределить метод активности onWindowFocusChanged(boolean hasFocus)
и отслеживать состояние своей активности.
Обычно, если над вашей деятельностью отображается какой-либо предупреждающий диалог, активность не onPause()
и onResume()
. Но он теряет фокус на показанном диалоговом окне предупреждения и получает его, когда он отклоняется.