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

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

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

提前致谢!

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

【问题讨论】:

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

标签: android android-coordinatorlayout android-collapsingtoolbarlayout android-appbarlayout


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-10
    • 2016-02-18
    • 2016-04-23
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多