首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >支持库中的Snackbar不包括OnDismissListener()?

支持库中的Snackbar不包括OnDismissListener()?
EN

Stack Overflow用户
提问于 2015-06-04 09:01:16
回答 7查看 6.4K关注 0票数 20

我想实现最新的设计支持库中包含的新的Snackbar,但是它的提供方式似乎与我的直觉相反,而且我认为其他很多人都在使用它。

当用户执行一个重要的操作时,我希望允许他们通过Snackbar撤销它,但是似乎无法检测出何时取消它来执行该操作。这样做对我来说是有意义的:

  1. 用户做动作。
  2. 显示Snackbar和update UI,就好像操作已经完成一样(即数据似乎已发送到数据库,但实际上尚未完成)。
  3. 如果用户按下“撤销”,则还原UI更改。如果没有,则在关闭Snackbar时,它将发送数据。

但是,由于我没有看到任何可访问的OnDismissListener,因此我不得不:

  1. 用户做动作。
  2. 立即将信息发送到数据库并更新UI。
  3. 如果用户按下“撤销”,则向数据库发送另一个调用,以删除刚刚添加的数据并还原UI更改。

我真的很想避免对数据库进行两次调用,并且在应用程序知道它是安全的(用户已经避免按“撤销”)的情况下,只发送一个。我注意到通过EventListener在第三方库中有一些实现,但我真的很想继续使用Google库。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2015-08-24 19:44:01

现在它是有吗?

代码语言:javascript
复制
Snackbar.make(getView(), "Hi there!", Snackbar.LENGTH_LONG).setCallback( new Snackbar.Callback() {
                @Override
                public void onDismissed(Snackbar snackbar, int event) {
                    switch(event) {
                        case Snackbar.Callback.DISMISS_EVENT_ACTION:
                            Toast.makeText(getActivity(), "Clicked the action", Toast.LENGTH_LONG).show();
                            break;
                        case Snackbar.Callback.DISMISS_EVENT_TIMEOUT:
                            Toast.makeText(getActivity(), "Time out", Toast.LENGTH_LONG).show();
                            break;
                    }
                }

                @Override
                public void onShown(Snackbar snackbar) {
                    Toast.makeText(getActivity(), "This is my annoying step-brother", Toast.LENGTH_LONG).show();
                }
            }).setAction("Go away!", new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            }).show();
票数 24
EN

Stack Overflow用户

发布于 2015-07-04 20:33:14

查看我的助手类中的snackbar。

代码语言:javascript
复制
public class SnackbarUtils {

private static final String LOG_TAG = SnackbarUtils.class.getSimpleName();

private SnackbarUtils() {
}

public interface SnackbarDismissListener {
    void onSnackbarDismissed();
}

public static void showSnackbar(View rootView, String message, String actionMessage, View.OnClickListener callbacks, final SnackbarDismissListener dismissListener){
    Snackbar snackbar = Snackbar.make(rootView,message,Snackbar.LENGTH_LONG);
    snackbar.setAction(actionMessage,callbacks);
    if (dismissListener != null){
        snackbar.getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
            @Override
            public void onViewAttachedToWindow(View v) {

            }

            @Override
            public void onViewDetachedFromWindow(View v) {
                dismissListener.onSnackbarDismissed();
            }
        });
    }
    snackbar.show();
}
}
票数 4
EN

Stack Overflow用户

发布于 2015-06-07 03:41:41

我也有同样的问题,但是我提供了一个删除数据的“撤销”。

我就是这样处理的:

  • 假装数据已从db中删除(隐藏在UI中,这是一个项目列表)
  • 等到小吃店“应该”解散
  • 将删除调用发送到数据库
  • 如果用户使用撤销操作,则阻止挂起的DB调用。

这可能不适用于您,因为您正在插入数据,并且您可能(?)需要它在第一个操作后在数据库中可用,但是如果‘伪造’数据(在UI中)是可行的,它将工作。我的代码不是最优的,我会称之为黑客,但这是我在官方库中所能找到的最好的代码。

代码语言:javascript
复制
    // Control objects
    boolean canRemoveData = true;
    Object removedData = getData(id);
    UI.remove(id);

    // Snackbar code
    Snackbar snackbar = Snackbar.make(view, "Data removed", Snackbar.LENGTH_LONG);
    snackbar.setAction("Undo", new View.OnClickListener() {
        @Override
        public void onClick(View v){
            canRemoveData = false;

            DB.remove(id);
        }
    });

    // Handler to time the dismissal of the snackbar
    new Handler(getActivity().getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            if(canRemoveData){
                DB.remove(id);
            }
        }
    }, (int)(snackbar.getDuration() * 1.05f)); 
    // Here I am using a slightly longer delay before sending the db delete call,
    // just because I don't trust the accuracy of the Handler timing and I want
    // to be on the safe side. Either way this is dirty code, but the best I could do.

我的实际代码更复杂(处理canRemoveData在子类中无法访问而不是最终的问题,但这基本上就是我成功实现您所讲的目标的方式)。

希望有人能想出更好的解决方案。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30639470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档