具有多个捕捉点的 CoordinatorLayout

2023-11-23

这里我有一个相当复杂的动画,可以使用以下方法以简单的方式解决(我相信)协调器布局。它有3个状态:

  1. 初始(左屏幕)- 标题视图完全显示(橙色 背景):工具栏,灰色圆角矩形(实际上是那里的照片) 加上下面的一些其他视图(TextViews、RatingBar 等)
  2. 向上滚动内容(中间 屏幕) - 圆矩形正在放大,其上的绿色前景 alpha 级别不断变化,因此滚动时它会变成绿色(好吧,在这些屏幕上并不明显。绿色背景实际上是一个缩放的圆矩形,其上有绿色前景,并且是标题背景变成绿色而不是橙色的原因)
  3. 再次滚动(右屏幕)-标题的其余部分应该向上滚动

向下滚动内容应该会相应地导致视图以相反的方式出现。

CoordinatorLayout states

我有一些使用 CoordinatorLayout 的经验,但我真的不确定我是否理解如何处理 2 个锚点。我了解滚动标志的工作原理以及缩放(第 2 页)和更改前景 alpha 我需要一个自定义Behavior实现,但现在我无法理解如何在一个复杂的环境中处理所有这些。

到目前为止我发现的只是萨乌尔·莫利内罗的教程并且本教程带有示例.

因此,请对这里的糟糕描述表示歉意,我当然会更新我的问题,并在我在这个问题上取得一些成功时添加源代码,但现在我很高兴得到一些提示或教程我已经错过了。希望有人在项目中有类似的东西。

这是我的测试仓库与代码和here是我的链接布局.xml file.


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

<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旗帜。使用这些滚动标志,应用栏将不会重新出现(一旦折叠),直到内容顶部可见并将应用栏“拉”入视图。

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 上很卡顿。


这是这个概念的一个实现。为了简单起见,实现是在一个活动中:

enter image description here

滚动活动.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);
                }
            }
        });
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有多个捕捉点的 CoordinatorLayout 的相关文章

随机推荐

  • 如何在命令行上从 COM exe 中提取 TypeLib

    我最近需要生成一个互操作程序集 经过一番谷歌搜索后我发现tlbimp exe 我的下一个问题是我的 COM 库没有附带 tlb文件 进一步的谷歌搜索显示 类型库通常作为资源包含在 exe dll 中 果然 在 VS2010 中打开 exe
  • 为什么不调用 Destroy?

    鉴于以下 Delphi 代码 Foo is Free d on FormClose but TFoo Destroy没有被调用 因此Bar is not Freed 导致内存泄漏 我是否在这里错过了一些东西 或者 Foo Free 在某个时
  • 定义和分配属性之间的区别

    为对象分配属性和定义属性有什么区别 哪一个更好以及如何实现 This Object defineProperty obj p propDesc 或者简单地 obj p someValue Object defineProperty让您可以设
  • 使用 $.post 将对象集合传递到 MVC 控制器

    我们正在尝试使用 json 和 jQuery post 函数将对象集合从我们的页面发送到您的控制器 MVC 3 下面是我们的 js 代码以及控制器和对象定义 问题是 当对象被适当地发送到我们的控制器时 它的成员变量没有被填充 Coords
  • jquery 调用命名函数的点击事件

    我有一个 jQueryonClick处理程序 用匿名函数编写 如下所示 selector on click function do something 我将概括在命名函数中提取逻辑的匿名函数 这促使我执行以下操作 selector on c
  • 链接批处理脚本时出现意外的双 & 符号/管道行为

    我的 foo bat 文件 exit b 1 我在cmd提示符下执行的内容 foo bat echo OK Result exit b 1 OK 然而 当我使用双管时 不会出现回声 foo bat echo OK Result exit b
  • 您将如何编写一种简单的编程语言? [复制]

    这个问题在这里已经有答案了 可能的重复 设计简单编程语言的方法 学习编写编译器 我想编写一种语法类似于 QBasic 但更简单的编程语言 我希望它适合初学者 它的简单性将鼓励有抱负的程序员不要放弃并让他们对编程产生兴趣 例如 代替 QBas
  • 如何确定子例程是否正在使用调用者的 eval 内调用?

    我仍在学习 Perl 我的任务是使用caller确定是否正在从某个子程序调用eval在任何更高的级别 我应该想出一些代码来测试它并打印Yes如果它来自eval or No如果不是的话 我找不到任何关于如何使用的好例子caller在网上 想知
  • 如何在 Windows XP 中的可执行文件上设置处理器关联?

    我有一个带有第三方应用程序的四核系统 偶尔会旋转多个进程 始终是相同的可执行文件 但有多个实例 并占用 100 的 CPU 时间 我还在同一个机器上运行了几个 Web 服务 IIS 和第三方 所有核心都繁忙的问题是 它会使第三方 Web 服
  • Visual Studio 2015 测试资源管理器看不到 XUnit dnx 特征

    Visual Studio 2015 测试资源管理器无法识别我的测试特征 当我将其添加到 DNX 项目中的测试时 Trait Category Test 该测试仍然显示在测试资源管理器中的 无特征 组下 按特征对测试进行分组时 看起来这已经
  • 避免“使用未分配的局部变量”错误

    我有两种与此等效的方法 请原谅这个人为的示例 public void WithResource Action
  • 从流启动进程

    我有一个包含 PDF 文件的内存流 是否可以在不保存到硬盘的情况下查看 PDF Process Start 仅采用路径而不采用流 谢谢 只能通过用 C 实现您自己的伪文件系统 以某种方式将其安装为 Windows 中的磁盘 并让它拦截打开的
  • 如何在家庭环境中使用化石 (DVCS)?

    我正在尝试将化石作为我的新版本控制系统 因为我是一个致力于小型项目的孤独开发人员 我开始测试化石 但遇到了一个 可能是主要的新手 问题 如何推送或拉取到另一个目录 这在 Hg 上很容易 Fossil pull 或push 命令需要URL 而
  • 带有 libxml 的 Swift 框架

    我有使用 KissXML Objective C 库的 Swift Framework 项目 KissXML 内部使用 libxml 当我构建 xcode 项目 Xcode 6 beta 5 时 出现以下错误 error
  • set_union 与多集容器?

    当一个或两个输入容器是具有重复对象的多重集时 算法 std set union 的返回是什么 傻瓜会迷路吗 我们假设例如 multiset
  • 使用 Smtp.mail.microsoftonline.com 发送电子邮件

    上下文 我们是一家小公司 没有 Exchange Server 或任何专用服务器 但我们仍然需要拥有 发送电子邮件 我们决定使用微软在线服务 MOS 目标 我们有一个 Web 服务器 带有 IIS 6 0 的 Windows Server
  • 自定义 Laravel Passport 响应未经身份验证

    目前 我使用 Laravel 中使用护照功能制作的 api 具有登录 注册 更新和删除功能 使用此 api 插入数据和从数据库获取数据一切正常 现在我想知道 当令牌过期时 如何自定义 api 的响应 令牌的过期也正常工作 它会自动显示此消息
  • 如何检查 Android SQLite 数据库中是否存在表?

    我有一个android应用程序 需要检查数据库中是否已有记录 如果没有 则处理一些事情并最终插入它 如果数据确实存在 则只需从数据库中读取数据 我正在使用 SQLiteOpenHelper 的子类来创建并获取 SQLiteDatabase
  • XML 声明标签区分大小写吗?

    我有一个可能非常简单 愚蠢的问题 但我在任何地方都找不到答案 我需要对此非常确定 我有来自不同供应商的各种 XML 文件 其中一个供应商向我提供了一个 XML 文件 其中包含日语字符 最初 我在处理 XML 文件时遇到了麻烦 我正在使用微软
  • 具有多个捕捉点的 CoordinatorLayout

    这里我有一个相当复杂的动画 可以使用以下方法以简单的方式解决 我相信 协调器布局 它有3个状态 初始 左屏幕 标题视图完全显示 橙色 背景 工具栏 灰色圆角矩形 实际上是那里的照片 加上下面的一些其他视图 TextViews RatingB