在SnackBar
内显示Activity
时,我有rootView
可用。但我需要在SnackBar
内显示Service
,其中我没有View
。我怎么能做到这一点?
作为背景故事:活动启动服务来执行任务。 Service
需要根据情况显示SnackBar
。我不想仅为此而绑定Service
。那么我怎么能做到这一点呢?通常我可以显示Toast
,但我需要用户能够阅读该消息并确认。
答案 0 :(得分:13)
Snackbar
需要显示View
,因此,如果您想根据Service
的状态在应用上显示小吃栏,则必须将其绑定到您的Activity
或通过LocalBroadcastManager
广播消息,并在View
上显示消息。
我认为还有其他方法,你必须以某种方式与你的Activity
或Fragment
沟通。
Snackbars不像只需要上下文的Toast ,所以如果你想从你的应用程序中显示它,我相信你不能使用Android提供的类。
<强>展示位置强>
Snackbars出现在屏幕上的大多数元素上方,它们相同 提升到浮动操作按钮。但是,它们的价格较低 高度比对话框,底部工作表和导航抽屉。
这不明确,但您可以得出结论,它只会显示在您的应用视图中。因此,您必须以某种方式与可见视图进行沟通。
广播消息的片段:
发件人(在您的服务上)
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);
}
接收者(在您的活动上)
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"));
}
有关约束服务的更多信息here。
关于LocalBroadcastManager
here on this question。
更新:您还可以使用EventBus与可见视图进行通信,因为它适用于发布商/订阅者时尚。您甚至可以使用Sticky events的概念来确保在应用再次可见后显示Snackbar
。
看看我的this answer如何使用事件总线。
答案 1 :(得分:4)
您始终可以通过Service
LocalBroadcastManager
发送广播
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("SERVICE_DID_SOMETHING"));
然后在Activity
中使用BroadcastReceiver
来显示Snackbar
private final ServiceReceiver _serviceReceiver = new ServiceReceiver();
@Override
protected void onResume() {
super.onResume();
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("SERVICE_DID_SOMETHING");
LocalBroadcastManager.getInstance(this).registerReceiver(_serviceReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(_serviceReceiver);
} catch (Exception ex) {
Log.e(TAG, "Error unregistering ServiceReceiver", ex);
}
}
// region ServiceReceiver
private class ServiceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: Show your Snackbar here...
}
}
// endregion
如果需要,您可以使用发送的Intent
传递其他数据,然后在BroadcastReceiver.onReceive(Context context, Intent intent)
答案 2 :(得分:1)
使用SDK提供的默认SnackBar
无法执行此操作,因为它始终需要视图。
为了达到您的目的,您可以使用一些模仿SnackBar的外部库,例如this one
答案 3 :(得分:0)
如何使用在多个活动中可见的应用程序上下文创建Snackbar:https://stackoverflow.com/a/37707741/1185087