小吃店解散后如何通知我?


79

我正在使用com.android.support:design:22.2.0图书馆的小吃店。我正在使用它撤消删除操作。为了使我的生活更轻松,我将使UI看起来好像实际上已从数据源中删除了东西,并且如果未按下小吃栏中的撤消按钮,则实际上是从数据源中执行删除。因此,我想知道小吃栏何时不再可见,因此可以安全删除这些项目。

我可以在Snackbar上调用getView(),但是我不确定应该使用哪个侦听器。我试过了,setOnSystemUiVisibilityChangeListener()但是那没用,我相信这只是针对系统状态栏的。

另外,Snackbar无法扩展,因为它具有私有构造函数。


1
此功能将在支持设计库的下一版本中
Tyler Pfaff

Answers:


177

Google设计库支持版本23中的Snackbar回调。请参见Snackbar文档Callback文档。然后,当小吃店被解雇时(以及显示时),您将收到通知,并且解雇的类型(如果这对您有用)也将得到通知:

snackbar.addCallback(new Snackbar.Callback() {

    @Override
    public void onDismissed(Snackbar snackbar, int event) {
      //see Snackbar.Callback docs for event details
      ...  
    }

    @Override
    public void onShown(Snackbar snackbar) {
       ...
    }
  });

12
setCallback()现在已弃用。使用addCallback()代替
jds17

36
snackbar.addCallback(new Snackbar.Callback() {

    @Override
    public void onDismissed(Snackbar snackbar, int event) {
        if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
            // Snackbar closed on its own
        }
    }

    @Override
    public void onShown(Snackbar snackbar) {
        ...
    }
});

3
很高兴提及该事件,因为单击actionText时也会调用onDismissed
Amro elaswar

2
在大多数情况下,最好是进行检查,if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)否则,如果用户手动关闭或另一个连续的小吃店取消了小吃店,则您的撤消逻辑将无法运行。
shyamal

感谢您的event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
留言

17

Snackbar.addCallback在Kotlin中

val snackBar = Snackbar
                .make(view, "Text Snackbar", Snackbar.LENGTH_LONG)
                .addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
                    override fun onShown(transientBottomBar: Snackbar?) {
                        super.onShown(transientBottomBar)
                    }

                    override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                        super.onDismissed(transientBottomBar, event)
                    }
                })

        val snackBarView = snackBar.view
        snackBarView.setBackgroundColor(Color.RED)
        snackBar.show()

16

最近,当我滚动和显示Snackback时,我自己偶然发现了这个问题,在第一个甚至消失之前,显示了太多内容。我必须找到一种方法来了解应用程序是否应该放下Snackbar。

我个人找到了这个解决方案。

确实,Snackbar本身不提供任何类型的状态/可见性侦听器,但是您仍然可以从Snackbar(getView();)中获取View Object。在View Object中,您可以使用多种方法来添加侦听器。

要实现它,您必须不使用常见的“多行合一” Toast / Snackbar用法,因为添加侦听器会返回void

我个人发现OnAttachStateChangeListener可以满足我的需求。

删除带有我的代码的快照程序,以防它可能对您有用。

Snackbar snack = Snackbar.make(getView(), "My Placeholder Text", Snackbar.LENGTH_LONG);

snack.getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
    @Override
        public void onViewAttachedToWindow(View v) {
            canDisplaySnackbar = false;
        }

    @Override
    public void onViewDetachedFromWindow(View v) {

        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                canDisplaySnackbar = true;

                }
        }, 1000);
    }
});
snack.show();

请注意,这只是我自己遇到的问题的实现,带有postDelayed Runnable的Handler可能甚至不适合您的情况。只是为了给出我建议使用已经拥有的代码片段的实现的一般概念。


4
and_dev的andswer现在是更好的答案。
Islam A. Hassan

12

要在显示或关闭快餐栏时通知您,可以通过setCallback(Callback)提供Snackbar.Callback。


setCallBack现在已弃用,请改用addCallBack
mjn42

5

当单击操作文本时,也会调用onDismissed,因为该原因需要设置一个条件,例如

event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT

现在,新代码如下所示。

final Snackbar snackBar = Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG);

snackbar.addCallback(new Snackbar.Callback() {

@Override
public void onDismissed(Snackbar snackbar, int event) {
 if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
        // Snackbar closed on its own
    }  
}

@Override
public void onShown(Snackbar snackbar) {
...
}
});
snackBar.show();

代码仅回答了一些令人鼓舞的问题,因为它们没有为以后的读者提供太多信息,请提供您所写内容的一些解释
WhatsThePoint

在大多数情况下,最好是进行检查,if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)否则,如果用户手动关闭某个小吃店或另一个连续的小吃店取消了小吃店,则您的撤消逻辑将无法运行。
shyamal




1
    snackbar.addCallback(new Snackbar.Callback() {
        public void onShown(Snackbar snackbar) {
           //  on show  
        }
 public void onDismissed(Snackbar snackbar, int event) {
          //  on dismiss  
        }
      });

请在代码段旁边提供描述/说明。
詹尼斯·F

1

我有和你完全一样的问题。我的解决方案是...

              final Snackbar povrati_obrisani_unos = Snackbar.make (coordinatorLayout, "Ponisti brisanje", Snackbar.LENGTH_INDEFINITE)
                    .addCallback (new Snackbar.Callback (){
                        @Override
                        public void onDismissed(Snackbar transientBottomBar, int event) {
                            super.onDismissed (transientBottomBar, event);
                            if(event==DISMISS_EVENT_SWIPE){//here we detect if snackbar is swipped away and not cliked (which is undo in my case)
                                Uri uriDelete = Uri.parse (obrisano.getImageuri ());
                                ContentResolver contentResolver = getContentResolver();
                                contentResolver.delete (uriDelete, null, null);
                                Toast.makeText (MainActivity.this,
                                        "Ocitavanje i slika su trajno obrisani", Toast.LENGTH_SHORT).show ();
                            }

仅此而已,不想复制粘贴pastebar.action这是撤消操作。我想在这里尽可能清楚。

问候内纳德


0

感谢Kotlin中的@SergeyMilakov,它是:

@SuppressLint("WrongConstant") // Suppress an error when set duration.
private fun showSnackbar() {
    val DURATION = 5000

    Snackbar.make(view!!, "Remove item?"), DURATION).apply {
        setAction("Undo") {
            // Your action when a button is clicked.
        }
        addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
            /* override fun onShown(transientBottomBar: Snackbar?) {
                super.onShown(transientBottomBar)
                Timber.d("*** onShown")
            }*/

            override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                super.onDismissed(transientBottomBar, event)
                if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) {
                    // Your action when the Snackbar is closed and the button was not clicked.
                }

            }
        })
        view.setBackgroundColor(ContextCompat.getColor(context, R.color.black))
        setActionTextColor(ContextCompat.getColor(context, R.color.yellow))
        show()
    }
}

请注意Snackbar,即使您移至其他屏幕(例如,返回),也会显示。因此,不要忘记检查是否在正确的屏幕上进行操作。

另外Snackbar屏幕旋转后不会恢复。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.