当从 Activity
中显示一个 SnackBar
时,我有可用的 rootView
。但是我需要从 Service
中显示一个 SnackBar
,而我没有可用的 View
。我怎样才能做到这一点?
作为背景故事:一个 Activity 启动一个服务来完成一个任务。 Service
需要根据情况显示 SnackBar
。我不想为此绑定(bind)到 Service
。那么我该如何实现呢?通常我可以显示一个 Toast
,但我需要用户能够阅读消息并进行确认。
最佳答案
Snackbar
需要一个 View
显示,所以如果你想根据你的状态在你的应用程序上显示 snackbar Service
你必须将它绑定(bind)到你的 Activity
或通过 LocalBroadcastManager
广播消息并在您的 View
上显示一条消息。
我认为没有其他解决方法,您必须以某种方式与您的 Activity
或 Fragment
进行通信。
Snackbars 不像 Toasts 那样只需要一个上下文,所以如果你想在你的应用程序外显示它,我相信你不能使用 Android 提供的类。
来自 design guidelines :
Placement
Snackbars appear above most elements on screen, and they are equal in elevation to the floating action button. However, they are lower in elevation than dialogs, bottom sheets, and navigation drawers.
虽然不是很明确,但您可以得出结论,它只会显示在您的应用 View 中。因此,同样,您必须以某种方式与您的可见 View 进行通信。
广播消息的 fragment :
发件人(在您的服务上)
private void doSendBroadcast(String message) {
Intent it = new Intent("EVENT_SNACKBAR");
if (!TextUtils.isEmpty(message))
it.putExtra(EXTRA_RETURN_MESSAGE,message);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(it);
}
接收者(在您的 Activity 上)
private BroadcastReceiver mMessageReceiver = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Other stuff.
mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Do something
}
};
}
@Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("EVENT_SNACKBAR"));
}
关于绑定(bind)服务的更多信息 here .
关于LocalBroadcastManager
here on this question .
更新:您还可以使用 EventBus与您的可见 View 进行通信,因为它以发布者/订阅者方式工作。您甚至可以利用 Sticky events 的概念确保在应用程序再次可见时显示 Snackbar
。
看看this answer关于如何使用事件总线的我的。
关于android - 从服务内部显示 Snackbar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34863038/