在服务中显示Snackbar

时间:2016-01-18 19:58:22

标签: android android-layout service android-snackbar

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

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

4 个答案:

答案 0 :(得分:13)

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

我认为还有其他方法,你必须以某种方式与你的ActivityFragment沟通。

Snackbars不像只需要上下文的Toast ,所以如果你想从你的应用程序中显示它,我相信你不能使用Android提供的类。

来自design guidelines

  

<强>展示位置

     

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