检测 AppBarLayout/CollapsingToolbarLayout 何时完全展开
Detecting when AppBarLayout/CollapsingToolbarLayout is completely expanded
我有一个使用新 CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout 范例的片段,我希望能够检测到折叠工具栏何时完全展开,以便我可以对它所在的整个片段执行操作,例如从堆栈中弹出片段并转到一个新的片段,解散该片段。我有关闭代码,我只需要知道什么时候和什么时候不使用它。
我用 AppBarLayout.OnOffsetChangedListener 做了一些试验,但运气不佳。有没有办法用它来确定什么时候完全展开,或者有没有人知道更喜欢的方法?
提前致谢!
编辑:
我还看到 AppBarLayout.setExpanded(...) 有几个实现,但 AppBarLayout.getExpanded() 或类似的东西没有,所以我也被难住了。
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);
}
}
我的解决方案基于创建自定义视图。首先创建一个 class 扩展原生 AppBarLayout:
public class CustomAppBar extends AppBarLayout { ....
然后在 class 中设置一个 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
}
然后我们必须访问视图的状态,因此在您的自定义视图中创建一个私有布尔值 class,并在您的视图开始展开或折叠时将其设置为 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 class
中使用 getter 来获取布尔值的状态
public boolean isExpanded() {
return isExpanded;
}
接下来是去你的 xml,在那里使用你的自定义视图,然后在 Acivity 或 Fragment 中获取视图并使用方法来了解 AppBar 状态
我知道,这可能有点晚了,但是探索 AppBArLayout 的源代码我发现,AppBarLayout.OnOffsetChangedListener 只是翻译了AppBar 行为的 int getTopAndBottomOffset()。
因此您可以随时使用此代码来定义 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;
}
我有一个使用新 CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout 范例的片段,我希望能够检测到折叠工具栏何时完全展开,以便我可以对它所在的整个片段执行操作,例如从堆栈中弹出片段并转到一个新的片段,解散该片段。我有关闭代码,我只需要知道什么时候和什么时候不使用它。
我用 AppBarLayout.OnOffsetChangedListener 做了一些试验,但运气不佳。有没有办法用它来确定什么时候完全展开,或者有没有人知道更喜欢的方法?
提前致谢!
编辑: 我还看到 AppBarLayout.setExpanded(...) 有几个实现,但 AppBarLayout.getExpanded() 或类似的东西没有,所以我也被难住了。
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);
}
}
我的解决方案基于创建自定义视图。首先创建一个 class 扩展原生 AppBarLayout:
public class CustomAppBar extends AppBarLayout { ....
然后在 class 中设置一个 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
}
然后我们必须访问视图的状态,因此在您的自定义视图中创建一个私有布尔值 class,并在您的视图开始展开或折叠时将其设置为 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 class
中使用 getter 来获取布尔值的状态public boolean isExpanded() {
return isExpanded;
}
接下来是去你的 xml,在那里使用你的自定义视图,然后在 Acivity 或 Fragment 中获取视图并使用方法来了解 AppBar 状态
我知道,这可能有点晚了,但是探索 AppBArLayout 的源代码我发现,AppBarLayout.OnOffsetChangedListener 只是翻译了AppBar 行为的 int getTopAndBottomOffset()。
因此您可以随时使用此代码来定义 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;
}