具有多个捕捉点的CoordinatorLayout [英] CoordinatorLayout with multiple snapping points

本文介绍了具有多个捕捉点的CoordinatorLayout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里,我有一个非常复杂的动画,可以使用

Here I've got quite a complex animation that may be resolved (I believe) in a simple way using the CoordinatorLayout. It has 3 states:

  1. 初始(左屏幕)-标题视图完整显示(橙色 背景):工具栏,灰色的圆角矩形(实际上是那里的一张照片) 以及下面的其他一些视图(TextViews,RatingBar等)
  2. 向上滚动内容(中间 屏幕)-roundrect正在放大,并且其上具有变化的绿色前景alpha电平,因此滚动时它变为绿色(嗯,在这些屏幕上并不明显.绿色背景实际上是缩放的roundrect,其上具有绿色前景,并且是标题背景变成绿色而不是橙色的原因
  3. 再次滚动(右屏幕)-标题的其余部分应向上滚动
  1. Initial (left screen) - Header view is shown fully (orange background): Toolbar, grey roundrect (it's actually a photo there) plus some other views below (TextViews, RatingBar etc)
  2. Scrolling the content up (middle screen) - roundrect is zooming up with a changing green foreground alpha level over it, so it becomes green while scrolling (well, it is not obvious with these screens. Green background is actually a zoomed roundrect with a green foreground over it, and that is the cause the header background becomes green and not orange)
  3. Scrolling once more (right screen) - the rest of the header should be scrolled up

向下滚动内容应导致视图以相反的方式出现.

Scrolling down the content should lead to the appearing of the views in a reverse way accordingly.

我有一些使用CoordinatorLayout的经验,但是我真的不确定我是否了解如何处理2个锚点.我了解滚动标记的工作方式以及缩放(第2页)和更改前景alpha的工作方式,我需要自定义

I had some experience working with the CoordinatorLayout, but I'm really not sure I understand how to handle 2 anchor points. I understand how the scroll flags work and that for zooming (p. 2) and for changing the foreground alpha I need a custom Behavior implementation, but for now I cannot understand how shall I handle all of this in a complex.

到目前为止,我发现的只是SaúlMolinero的教程,还有本教程的示例.

All I've found so far is Saúl Molinero's tutorial and also this tutorial with examples.

因此,对于这里的简短说明,我们深表歉意,我将更新我的问题,当我在此问题上取得一些成功时,将添加源代码,但是现在我很高兴获得一些提示或教程我错过了.希望有人在项目中有类似的东西.

So please sorry for the poor description here, I'll update my question of course and will add the source code when I have some success with this issue, but for now I'd be glad to get some hints maybe or tutorials I've missed. Hope someone had something similar in the projects.

这是我的测试仓库,其中包含代码和

Here's my test repo with the code and here is a link to my layout.xml file.

推荐答案

您只需设置滚动标志即可获得两个捕捉点,如下所示:

You can get two snapping points with just setting the scroll flags as follows:

<android.support.design.widget.CollapsingToolbarLayout
    ...stuff...
    app:layout_scrollFlags="scroll|enterAlways|snap">

因此,完全展开是一个停止点,只有可见的工具栏是第二个停止点.进一步滚动视图时,工具栏消失.因此,这就是您希望向上滚动时工作的方式.

So, fully expanded is one stopping point and with just the toolbar visible is the second stopping point. When the view is scrolled further, the toolbar disappears. So this is how you want things to work when scrolling up.

现在,当应用栏完全折叠时,向下滚动时,应用栏将立即开始显示.这并不奇怪,因为enterAlways就是这样做的.如果内容的顶部已滚动到视线之外,则只有在应用栏完全展开之后,您才会再次看到它.因此,如果这是您想要的行为,我们将仅在此处停止.

Now when the app bar is fully collapsed, the app bar will start showing immediately when scrolling down. That is not a surprise, since that is what enterAlways does. If the top of the content has been scrolled out of view, then you won't see it again until after the app bar is fully expanded. So, if this is the behavior you want, we'll just stop there.

但是,我认为您想要的是上面概述的退出行为,但具有不同的进入行为.如果按如下所示设置滚动标志,则会出现延迟进入行为:

However, I think that what you want is the exiting behavior outlined above but with a different entry behavior. You will get the late entry behavior if you set the scroll flags as follows:

<android.support.design.widget.CollapsingToolbarLayout
    ...stuff...
    app:layout_scrollFlags="scroll|snap">

这只是删除了enterAlways标志.使用这些滚动标记,直到内容的顶部可见并将应用栏拉"到视图中,应用栏才会重新出现(一旦折叠).

This just deleted the enterAlways flag. With these scroll flags, the app bar will not reappear (once collapsed) until the top of the content is visible and "pulls" the app bar into view.

因此,一种解决方案(可能有很多)是编写一种新行为,该行为将附加到AppBarLayout 上,一些代码将在应用栏完全打开后更改滚动标志.折叠并在再次打开时将其改回.这样,您可以将行为更改为所需的行为,并且仍然使用Android机制来确定视图级别的特定操作.可以在自定义视图或活动中完成此操作-可以访问应用程序栏的滚动状态和滚动标志的任何位置.也可以通过某种行为来完成,但这可能不是最佳选择.

So, one solution (of what is probably many) is to write a new behavior that will be attached to the AppBarLayout some code that will change the scroll flags once the app bar is fully collapsed and change them back as it opens again. That way you can change the behavior to be what you want and still use the Android machinery to figure out what the specific operations are at the view level. This can be done in a custom view or in the activity - wherever you have access to the scroll state of the app bar and the scrolling flags. It can also be done in a behavior but that is probably not the best place for it.

哦,正如您所发现的那样,在API 26上捕捉非常困难.

Oh, and as you have discovered, snapping is janky on API 26.

这里是概念的实现.为简单起见,该实现是在一个活动中进行的:

Here is an implementation of the concept. For simplicity, the implementation is in an 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);
                }
            }
        });
    }
}

这篇关于具有多个捕捉点的CoordinatorLayout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆