具有多个捕捉点的 CoordinatorLayout
CoordinatorLayout with multiple snapping points
-
android
-
android-animation
-
android-coordinatorlayout
-
android-collapsingtoolbarlayout
-
android-nestedscrollview
这里我有一个相当复杂的动画,可以使用 CoordinatorLayout 以简单的方式解决(我相信)。它有 3 个状态:
- 初始(左侧屏幕)- Header 视图已完全显示(橙色
背景):工具栏,灰色 roundrect(它实际上是一张照片)
加上下面的一些其他视图(TextViews、RatingBar 等)
- 向上滚动内容(中间
屏幕)- roundrect 正在放大,其上有一个不断变化的绿色前景 alpha 级别,因此它在滚动时变为绿色(好吧,在这些屏幕上并不明显。绿色背景实际上是一个放大的 roundrect,上面有一个绿色前景,而且是 header 背景变成绿色而不是橙色的原因)
- 再次滚动(右侧屏幕)- header 的其余部分应向上滚动
向下滚动内容应该会相应地以相反的方式显示视图。
我有一些使用 CoordinatorLayout 的经验,但我真的不确定我是否理解如何处理 2 个锚点。我了解滚动标志的工作原理以及用于缩放(第 2 页)和更改前景 alpha 的工作原理我需要一个自定义 Behavior 实现,但现在我无法理解如何在一个复杂的环境中处理所有这些。
目前我找到的只有 Saúl Molinero's tutorial and also this tutorial with examples。
很抱歉这里的描述不佳,我当然会更新我的问题,当我在这个问题上取得一些成功时会添加源代码,但现在我很乐意得到一些提示或我错过的教程。希望有人在项目中有类似的东西。
这是我的 test repo with the code and here 是我的 layout.xml 文件的 link。
只需设置滚动标志即可获得两个捕捉点,如下所示:
<android.support.design.widget.CollapsingToolbarLayout
...stuff...
app:layout_scrollFlags="scroll|enterAlways|snap">
因此,完全展开是一个停止点,仅显示工具栏是第二个停止点。当进一步滚动视图时,工具栏消失。这就是您希望向上滚动时的工作方式。
现在,当应用栏完全折叠时,向下滚动时应用栏将立即开始显示。这并不奇怪,因为 enterAlways
就是这样做的。如果内容的顶部已经滚出视图,那么在应用栏完全展开之前您将不会再次看到它。所以,如果这是您想要的行为,我们就到此为止。
但是,我认为您想要的是上面概述的退出行为,但具有不同的进入行为。如果按如下方式设置滚动标志,您将获得延迟进入行为:
<android.support.design.widget.CollapsingToolbarLayout
...stuff...
app:layout_scrollFlags="scroll|snap">
这只是删除了 enterAlways
标志。使用这些滚动标志,应用栏将不会重新出现(一旦折叠),直到内容顶部可见并且 "pulls" 应用栏进入视图。
因此,一个解决方案(可能有很多)是编写一个新的行为,该行为将附加到 AppBarLayout
一些将改变滚动的代码应用栏完全折叠后标记,并在再次打开时将其改回。这样您就可以将行为更改为您想要的行为,并且仍然使用 Android 机制来确定视图级别的特定操作。这可以在自定义视图或 activity 中完成 - 无论您可以访问应用栏的滚动状态和滚动标志。它也可以在行为中完成,但这可能不是最好的地方。
哦,正如您所发现的那样,在 API 26.
上捕捉是卡顿的
这里是这个概念的一个实现。为简单起见,实现在 activity:
中
ScrollingActivity.java
public class ScrollingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrolling);
final AppBarLayout appBar = (AppBarLayout) findViewById(R.id.app_bar);
appBar.post(new Runnable() {
@Override
public void run() {
CollapsingToolbarLayout toolbarLayout =
(CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
setupAppBar(appBar, toolbarLayout);
}
});
}
private void setupAppBar(AppBarLayout appBar, final CollapsingToolbarLayout toolbarLayout) {
// Scroll range is positive but offsets are negative. Make signs agree for camparisons.
final int mScrollRange = -appBar.getTotalScrollRange();
appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
private boolean mAppBarCollapsed = false;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (verticalOffset == mScrollRange) { // App bar just collapsed
mAppBarCollapsed = true;
AppBarLayout.LayoutParams lp =
(AppBarLayout.LayoutParams) toolbarLayout.getLayoutParams();
int flags = lp.getScrollFlags()
& ~AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS;
lp.setScrollFlags(flags);
toolbarLayout.setLayoutParams(lp);
} else if (mAppBarCollapsed) { // App bar is opening back up
mAppBarCollapsed = false;
AppBarLayout.LayoutParams lp =
(AppBarLayout.LayoutParams) toolbarLayout.getLayoutParams();
int flags = lp.getScrollFlags()
| AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS;
lp.setScrollFlags(flags);
toolbarLayout.setLayoutParams(lp);
}
}
});
}
}
android
android-animation
android-coordinatorlayout
android-collapsingtoolbarlayout
android-nestedscrollview
这里我有一个相当复杂的动画,可以使用 CoordinatorLayout 以简单的方式解决(我相信)。它有 3 个状态:
- 初始(左侧屏幕)- Header 视图已完全显示(橙色 背景):工具栏,灰色 roundrect(它实际上是一张照片) 加上下面的一些其他视图(TextViews、RatingBar 等)
- 向上滚动内容(中间 屏幕)- roundrect 正在放大,其上有一个不断变化的绿色前景 alpha 级别,因此它在滚动时变为绿色(好吧,在这些屏幕上并不明显。绿色背景实际上是一个放大的 roundrect,上面有一个绿色前景,而且是 header 背景变成绿色而不是橙色的原因)
- 再次滚动(右侧屏幕)- header 的其余部分应向上滚动
向下滚动内容应该会相应地以相反的方式显示视图。
我有一些使用 CoordinatorLayout 的经验,但我真的不确定我是否理解如何处理 2 个锚点。我了解滚动标志的工作原理以及用于缩放(第 2 页)和更改前景 alpha 的工作原理我需要一个自定义 Behavior 实现,但现在我无法理解如何在一个复杂的环境中处理所有这些。
目前我找到的只有 Saúl Molinero's tutorial and also this tutorial with examples。
很抱歉这里的描述不佳,我当然会更新我的问题,当我在这个问题上取得一些成功时会添加源代码,但现在我很乐意得到一些提示或我错过的教程。希望有人在项目中有类似的东西。
这是我的 test repo with the code and here 是我的 layout.xml 文件的 link。
只需设置滚动标志即可获得两个捕捉点,如下所示:
<android.support.design.widget.CollapsingToolbarLayout
...stuff...
app:layout_scrollFlags="scroll|enterAlways|snap">
因此,完全展开是一个停止点,仅显示工具栏是第二个停止点。当进一步滚动视图时,工具栏消失。这就是您希望向上滚动时的工作方式。
现在,当应用栏完全折叠时,向下滚动时应用栏将立即开始显示。这并不奇怪,因为 enterAlways
就是这样做的。如果内容的顶部已经滚出视图,那么在应用栏完全展开之前您将不会再次看到它。所以,如果这是您想要的行为,我们就到此为止。
但是,我认为您想要的是上面概述的退出行为,但具有不同的进入行为。如果按如下方式设置滚动标志,您将获得延迟进入行为:
<android.support.design.widget.CollapsingToolbarLayout
...stuff...
app:layout_scrollFlags="scroll|snap">
这只是删除了 enterAlways
标志。使用这些滚动标志,应用栏将不会重新出现(一旦折叠),直到内容顶部可见并且 "pulls" 应用栏进入视图。
因此,一个解决方案(可能有很多)是编写一个新的行为,该行为将附加到 一些将改变滚动的代码应用栏完全折叠后标记,并在再次打开时将其改回。这样您就可以将行为更改为您想要的行为,并且仍然使用 Android 机制来确定视图级别的特定操作。这可以在自定义视图或 activity 中完成 - 无论您可以访问应用栏的滚动状态和滚动标志。它也可以在行为中完成,但这可能不是最好的地方。AppBarLayout
哦,正如您所发现的那样,在 API 26.
上捕捉是卡顿的这里是这个概念的一个实现。为简单起见,实现在 activity:
中ScrollingActivity.java
public class ScrollingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrolling);
final AppBarLayout appBar = (AppBarLayout) findViewById(R.id.app_bar);
appBar.post(new Runnable() {
@Override
public void run() {
CollapsingToolbarLayout toolbarLayout =
(CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
setupAppBar(appBar, toolbarLayout);
}
});
}
private void setupAppBar(AppBarLayout appBar, final CollapsingToolbarLayout toolbarLayout) {
// Scroll range is positive but offsets are negative. Make signs agree for camparisons.
final int mScrollRange = -appBar.getTotalScrollRange();
appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
private boolean mAppBarCollapsed = false;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (verticalOffset == mScrollRange) { // App bar just collapsed
mAppBarCollapsed = true;
AppBarLayout.LayoutParams lp =
(AppBarLayout.LayoutParams) toolbarLayout.getLayoutParams();
int flags = lp.getScrollFlags()
& ~AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS;
lp.setScrollFlags(flags);
toolbarLayout.setLayoutParams(lp);
} else if (mAppBarCollapsed) { // App bar is opening back up
mAppBarCollapsed = false;
AppBarLayout.LayoutParams lp =
(AppBarLayout.LayoutParams) toolbarLayout.getLayoutParams();
int flags = lp.getScrollFlags()
| AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS;
lp.setScrollFlags(flags);
toolbarLayout.setLayoutParams(lp);
}
}
});
}
}