当 Snackbar 自行关闭时,如何通知我?
How can I be notified when a Snackbar has dismissed itself?
我正在使用 com.android.support:design:22.2.0
库中的 Snackbar。我用它来撤消删除。为了让我的生活更轻松,我打算让 UI 看起来像是从数据源中实际删除的东西,如果没有按下快餐栏中的撤消按钮,实际上从数据源中执行删除.所以,我想知道 Snackbar 何时不再可见,以便删除这些项目是安全的。
我可以在 Snackbar 上调用 getView(),但我不确定应该使用哪个侦听器。我试过 setOnSystemUiVisibilityChangeListener()
但没有用,我相信它只适用于系统状态栏。
此外,Snackbar 不能扩展,因为它有一个私有构造函数。
目前您无法实现。
当 snackbar 消失时没有调用监听器。
最简单的方法是暂时将记录保存在别处(即使是局部变量),然后在他们碰巧按下撤消按钮时重新插入它。
当前无法在 Snackbar 完成显示时收到通知。
在此线程中,基于 Snackbar 显示期间的计时器讨论了一种解决方法。
此解决方法需要考虑的一个问题是 Snackbar 持续时间可能会重新启动。 material design specification for Snackbar 表示如果显示不相关的对话框或弹出窗口,就会发生这种情况。
最近我自己在滚动和显示 Snackback 时偶然发现了这个问题,在第一个甚至消失之前显示了太多。我必须找到一种方法来了解该应用程序是否应该放置 Snackbar。
我个人找到了这个解决方案。
Snackbar 本身确实不提供任何类型的侦听器,因为它是 state/visibility,但您仍然可以从 Snackbar ( getView(); ) 中获取视图对象。从视图对象中,您有机会使用多种方法来添加侦听器。
要实现它你必须走出常见的 "all-in-one-line" Toast/Snackbar 用法,因为添加监听器 returns void .
我个人发现 OnAttachStateChangeListener 可以满足我的需求。
用我的代码放一个 snipper 以防它对你有用。
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 的处理程序甚至可能不适合您的情况。这只是为了给出我建议使用我已经拥有的片段的实现的一般概念。
要在显示或关闭快餐栏时收到通知,您可以通过 setCallback(Callback) 提供 Snackbar.Callback。
Google 设计库在版本 23 中支持 Snackbar 回调。请参阅 Snackbar docs and Callback docs。
然后,当 Snackbar 被关闭时(以及显示时)以及关闭类型(如果这对您有用),您将收到通知:
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) {
...
}
});
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) {
...
}
});
setCallback
现已弃用,应使用 addCallback
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();
snackbar.addCallback(new Snackbar.Callback() {
public void onShown(Snackbar snackbar) {
// on show
}
public void onDismissed(Snackbar snackbar, int event) {
// on dismiss
}
});
Snackbar.addCallback 在科特林
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()
感谢 Kotlin 中的 它是:
@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
屏幕旋转后不恢复。
我和你的问题一模一样。我的解决方案是...
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 ();
}
就是这样,不想复制粘贴snackbar.action这是撤消。想在这里尽可能说清楚。
问候内纳德
在 Kotlin 中,这对我有用:
Snackbar.make(
binding.root,
getString(R.string.ticket_posted),
LENGTH_LONG)
.setAction(getString(R.string.undo)) {
Log.d(TAG, "Try to undo ticket $key")
}
.addCallback(object : BaseCallback<Snackbar>() {
override fun onDismissed(
transientBottomBar: Snackbar?,
event: Int
) {
super.onDismissed(transientBottomBar, event)
if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
Log.d(TAG, "Try to reset")
}
}
})
.show()
}
我正在使用 com.android.support:design:22.2.0
库中的 Snackbar。我用它来撤消删除。为了让我的生活更轻松,我打算让 UI 看起来像是从数据源中实际删除的东西,如果没有按下快餐栏中的撤消按钮,实际上从数据源中执行删除.所以,我想知道 Snackbar 何时不再可见,以便删除这些项目是安全的。
我可以在 Snackbar 上调用 getView(),但我不确定应该使用哪个侦听器。我试过 setOnSystemUiVisibilityChangeListener()
但没有用,我相信它只适用于系统状态栏。
此外,Snackbar 不能扩展,因为它有一个私有构造函数。
目前您无法实现。
当 snackbar 消失时没有调用监听器。
最简单的方法是暂时将记录保存在别处(即使是局部变量),然后在他们碰巧按下撤消按钮时重新插入它。
当前无法在 Snackbar 完成显示时收到通知。
在此线程中,基于 Snackbar 显示期间的计时器讨论了一种解决方法。
此解决方法需要考虑的一个问题是 Snackbar 持续时间可能会重新启动。 material design specification for Snackbar 表示如果显示不相关的对话框或弹出窗口,就会发生这种情况。
最近我自己在滚动和显示 Snackback 时偶然发现了这个问题,在第一个甚至消失之前显示了太多。我必须找到一种方法来了解该应用程序是否应该放置 Snackbar。
我个人找到了这个解决方案。
Snackbar 本身确实不提供任何类型的侦听器,因为它是 state/visibility,但您仍然可以从 Snackbar ( getView(); ) 中获取视图对象。从视图对象中,您有机会使用多种方法来添加侦听器。
要实现它你必须走出常见的 "all-in-one-line" Toast/Snackbar 用法,因为添加监听器 returns void .
我个人发现 OnAttachStateChangeListener 可以满足我的需求。
用我的代码放一个 snipper 以防它对你有用。
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 的处理程序甚至可能不适合您的情况。这只是为了给出我建议使用我已经拥有的片段的实现的一般概念。
要在显示或关闭快餐栏时收到通知,您可以通过 setCallback(Callback) 提供 Snackbar.Callback。
Google 设计库在版本 23 中支持 Snackbar 回调。请参阅 Snackbar docs and Callback docs。 然后,当 Snackbar 被关闭时(以及显示时)以及关闭类型(如果这对您有用),您将收到通知:
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) {
...
}
});
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) {
...
}
});
setCallback
现已弃用,应使用 addCallback
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();
snackbar.addCallback(new Snackbar.Callback() {
public void onShown(Snackbar snackbar) {
// on show
}
public void onDismissed(Snackbar snackbar, int event) {
// on dismiss
}
});
Snackbar.addCallback 在科特林
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()
感谢 Kotlin 中的
@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
屏幕旋转后不恢复。
我和你的问题一模一样。我的解决方案是...
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 ();
}
就是这样,不想复制粘贴snackbar.action这是撤消。想在这里尽可能说清楚。
问候内纳德
在 Kotlin 中,这对我有用:
Snackbar.make(
binding.root,
getString(R.string.ticket_posted),
LENGTH_LONG)
.setAction(getString(R.string.undo)) {
Log.d(TAG, "Try to undo ticket $key")
}
.addCallback(object : BaseCallback<Snackbar>() {
override fun onDismissed(
transientBottomBar: Snackbar?,
event: Int
) {
super.onDismissed(transientBottomBar, event)
if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
Log.d(TAG, "Try to reset")
}
}
})
.show()
}