13

SnackBar从内部显示 a时Activity,我有rootView可用的。但我需要SnackBar从 a 内部显示 a Service,我没有View可用的。我怎么能做到这一点?

作为背景故事:一个活动启动一个服务来完成一项任务。Service需要根据SnackBar情况显示。我不想为此绑定Service。那么我怎么能做到这一点呢?通常我可以显示 a Toast,但我需要用户能够阅读消息并确认。

4

4 回答 4

17

Snackbar需要显示,因此View如果您想根据您的状态在您的应用程序上显示小吃吧,您Service必须将其绑定到您的Activity或通过广播消息LocalBroadcastManager并在您的View.

我认为没有其他方法可以解决它,您必须与您的ActivityFragment以某种方式进行交流。

Snackbars 不像 Toasts 只需要一个 context,所以如果你想在你的应用程序中显示它,我相信你不能使用 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"));
}

更多关于绑定服务的信息

关于LocalBroadcastManager 这个问题

更新:您还可以使用EventBus与您的可见视图进行通信,因为它以发布者/订阅者的方式工作。您甚至可以利用Sticky 事件的概念来确保Snackbar一旦应用再次可见,就会显示该事件。

看看我的这个关于如何使用事件总线的答案。

于 2016-01-18T20:05:43.603 回答
5

你总是可以通过LocalBroadcastManager你的Service

LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("SERVICE_DID_SOMETHING"));

然后在Activity使用 aBroadcastReceiver来显示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)

于 2016-01-18T20:05:32.117 回答
1

如何使用在多个活动中可见的应用程序上下文创建 Snackbar:https ://stackoverflow.com/a/37707741/1185087

于 2016-06-08T16:16:57.567 回答
-1

使用 SDK 提供的默认值是不可能SnackBar的,因为它总是需要一个视图。

为了达到您的目的,您可以使用一些模仿像这样的 SnackBar 的外部库

于 2016-01-18T20:11:26.897 回答