当用户执行任何操作时如何关闭 Snackbar?

Posted

技术标签:

【中文标题】当用户执行任何操作时如何关闭 Snackbar?【英文标题】:How to dismiss Snackbar when user does any action? 【发布时间】:2016-04-30 16:15:50 【问题描述】:

我可以显示这样的小吃店。

Snackbar snackbar = Snackbar.make(this.findViewById(android.R.id.content), "snackbar", Snackbar.LENGTH_INDEFINITE)
        .setAction("action", new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                // ...
            
        );
snackbar.show();

我的小吃店长度不定,我想要它。但是当用户执行任何操作时,例如滚动屏幕或触摸屏/视图,我想关闭快餐栏。我可以找到一些库和代码,但它们太复杂了。有没有简单的方法可以关闭小吃店?

【问题讨论】:

尝试使用OnTouchListener 【参考方案1】:

我假设您正在使用片段,因此您可以在片段主布局中设置一个 onTouchListener,并将其放入 snapbar.dismiss() 中。

如果您只想在滚动设置 onScrollListener 时关闭,并在事件中关闭小吃栏,这里是 recyclerview onScroll 的实现:

list.addOnScrollListener(new RecyclerView.OnScrollListener() 
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) 
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) 
                    snackbar.dismiss();
                    
                );

【讨论】:

【参考方案2】:

也许我找到了解决方案。我在我的视图组中添加了框架布局。谢谢节食者_h

为覆盖 IntercepterTouchEvent 创建自定义 Framelayout 类

private class InterceptTouchEventLayout extends FrameLayout 

    Snackbar mSnackbar;

    public InterceptTouchEventLayout(Context context) 
        super(context);
        setLayoutParams(new CoordinatorLayout.LayoutParams(
                CoordinatorLayout.LayoutParams.MATCH_PARENT,
                CoordinatorLayout.LayoutParams.MATCH_PARENT));
    

    public void setSnackbar(Snackbar snackbar) 
        mSnackbar = snackbar;
    

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) 
        int action = ev.getAction();
        switch (action) 
            case MotionEvent.ACTION_DOWN:
                if (mSnackbar != null && mSnackbar.isShown()) 
                    mSnackbar.dismiss();
                
                break;
        
        return super.onInterceptTouchEvent(ev);
    

我的 xml:

<FrameLayout
    ...>
    <ScrollView .../>
    <FrameLayout .../>
</FrameLayout>

获取最上面的FrameLayout

View contentView = this.findViewById(android.R.id.content);
View framLayout = ((ViewGroup) contentView).getChildAt(0);

添加自定义布局的写法

private void addInterceptLayoutToViewGroup(Snackbar snackbar) 
    View contentView = this.findViewById(android.R.id.content);
    ViewGroup vg = (ViewGroup) ((ViewGroup) contentView).getChildAt(0);
    if (!(vg.getChildAt(0) instanceof InterceptTouchEventLayout)) 
        InterceptTouchEventLayout interceptLayout =
                new InterceptTouchEventLayout(this);
        interceptLayout.setSnackbar(snackbar);
        for (int i = 0; i < vg.getChildCount(); i++) 
            View view = vg.getChildAt(i);
            vg.removeView(view);
            interceptLayout.addView(view);
        
        vg.addView(interceptLayout, 0);
     else 
        InterceptTouchEventLayout interceptLayout = 
                (InterceptTouchEventLayout) vg.getChildAt(0);
        interceptLayout.setSnackbar(snackbar);
    

所以,我可以这样使用!!!

Snackbar snackbar = Snackbar.make(this.findViewById(android.R.id.content), "text", Snackbar.LENGTH_INDEFINITE)
        .setAction("action", new View.OnClickListener() 

            @Override
            public void onClick(View v) 
                //...
            
        );
snackbar.show();
addInterceptLayoutToViewGroup(snackbar);

老实说,我的解决方案改变了视图树(?)。在那之后,我的xml可能是..

<FrameLayout
    ...>
    <InterceptTouchEventLayout
        ...>
        <ScrollView .../>
        <FrameLayout .../>
    </InterceptTouchEventLayout>
</FrameLayout>

【讨论】:

以上是关于当用户执行任何操作时如何关闭 Snackbar?的主要内容,如果未能解决你的问题,请参考以下文章

如何在关闭屏幕时关闭打开的 SnackBar?

防止 Snackbar 在操作单击时关闭

Snackbar 在操作点击时不会被关闭

关闭 Snackbar 时,FloatingActionButton 不会出现

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

Android Snackbar 的使用