检测 AppBarLayout/CollapsingToolbarLayout 何时完全展开

Posted

技术标签:

【中文标题】检测 AppBarLayout/CollapsingToolbarLayout 何时完全展开【英文标题】:Detecting when AppBarLayout/CollapsingToolbarLayout is completely expanded 【发布时间】:2015-11-19 17:38:21 【问题描述】:

我有一个使用新的 CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout 范例的片段,我希望能够检测折叠工具栏何时完全展开,以便我可以对其所在的整个片段执行操作,例如将片段从堆栈中弹出并转到新的片段,解除片段。我有解除代码工作,我只需要知道什么时候不使用它。

我对@9​​87654321@ 进行了一些试验,但运气不佳。有没有办法使用它来确定事物何时完全展开,或者有没有人知道的更首选的方法?

提前致谢!

编辑: 我还看到AppBarLayout.setExpanded(...) 有几个实现,但不是 AppBarLayout.getExpanded() 或类似的东西,所以我也被难住了。

【问题讨论】:

也许 appBarLayout.addOnOffsetChangedListener 可以提供帮助,但我发现它有问题,可能是我没有正确实现它。 您找到解决方案了吗?当工具栏部分折叠时,我试图阻止 ScrollRefreshLayout 刷新时遇到了同样的问题。 【参考方案1】:

API 中似乎没有任何内容,但以下内容似乎对我有用。它可能需要测试。

boolean fullyExpanded =
    (appBarLayout.getHeight() - appBarLayout.getBottom()) == 0;

编辑:上面的解决方案似乎确实有效,但由于我想在滚动应用栏时测试这种情况,我最终使用OnOffsetChangedListener 的以下解决方案。

class Frag extends Fragment implements AppBarLayout.OnOffsetChangedListener 

    private boolean appBarIsExpanded = true;
    private AppBarLayout appBarLayout;

    @Override 
    public void onActivityCreated(Bundle state) 
        super.onActivityCreated(state);
        appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);
    

    @Override
    public void onResume() 
        super.onResume();
        appBarLayout.addOnOffsetChangedListener(this);
    

    @Override
    public void onStop() 
        super.onStop();
        appBarLayout.removeOnOffsetChangedListener(this);
    

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) 
        appBarIsExpanded = (verticalOffset == 0);
     


【讨论】:

我最终放弃了为什么我首先要这样做的概念,但我会接受你的回答,因为你说它对你有用。谢谢! 这也不适合我。添加了接口的实现,但似乎没有被调用 @user1232726 您需要将侦听器附加到 AppBarLayout。我用一种方法更新了代码。如果您不关心潜在的泄漏,只需使用 appBarLayout.setOnScrollChangeListener(this) 即可。 你刚刚拯救了我的一天。谢谢。【参考方案2】:

我的解决方案基于创建自定义视图。首先创建一个扩展原生 AppBarLayout 的类:

public class CustomAppBar extends AppBarLayout  ....

然后在类中设置一个 addOnOffsetChangedListener 如下:

this.addOnOffsetChangedListener...

您可以通过在构造函数中设置或调用构造函数中的方法来完成上述操作。所以你需要构造函数,记得使用带有2个参数的构造函数才能添加到xml中

public CustomAppBar(Context context, AttributeSet attrs) 
        super(context, attrs);
//You can set the listener here or maybe call the method that set the listener

然后我们必须访问视图的状态,因此在您的自定义视图类中创建一个私有布尔值,如果您的视图开始展开或折叠,则将其设置为 true 或 false,在这种情况下,我的视图是默认的展开:

private boolean isExpanded = true;

现在您必须更新该布尔值的状态:

this.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() 
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) 
                if (verticalOffset == 0) 
                    isExpanded = true;
                 else 
                    isExpanded = false;
                
            
        );

下一步是通过在 CustomAppBar 类中使用 getter 来获取布尔值的状态

public boolean isExpanded() 
        return isExpanded;
    

接下来是转到你的xml,在那里使用你的自定义视图,然后在活动或片段中获取视图并使用方法来了解AppBar状态

【讨论】:

当您可以直接将OnOffsetChangedListener 添加到AppBarLayout 实例时,这似乎有点过头了。 如果您只打算使用该 AppBarLayout 一次:是的。但是如果不止一个activity需要知道AppBarLayout的状态,那么:这是一个DRY解决方案【参考方案3】:

我知道,这可能有点晚了,但是在探索我发现的 AppBArLayout 的源代码时,AppBarLayout.OnOffsetChangedListener 只是转换了 int getTopAndBottomOffset() 的值 AppBar 的行为。

因此,您可以随时使用此代码来定义 AppBarLayout 是否展开:

public boolean isAppBArExpanded(AppBarLayout abl) 
    final CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) abl.getLayoutParams()).getBehavior();
    return (behavior instanceof AppBarLayout.Behavior) ? (((AppBarLayout.Behavior) behavior).getTopAndBottomOffset() == 0) : false;

【讨论】:

以上是关于检测 AppBarLayout/CollapsingToolbarLayout 何时完全展开的主要内容,如果未能解决你的问题,请参考以下文章

行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)

行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)

[计算机视觉]人脸应用:人脸检测人脸对比五官检测眨眼检测活体检测疲劳检测

行人检测(人体检测)1:人体检测数据集(含下载链接)

行人检测(人体检测)2:YOLOv5实现人体检测(含人体检测数据集和训练代码)

行人检测和人脸检测和人脸关键点检测(C++/Android源码)