Android高级UI开发(二十一)AppBarLayout与CollapsingToolbarLayout一分钟组合出视差效果

举报
yd_57386892 发表于 2020/12/29 01:21:45 2020/12/29
【摘要】 今天继续看AppBarLayout的一个强大功能,那就是它结合CollapsingToolbarLayout可以1分钟作出我们常用的滑动视差效果,效果图如下: 1. 布局activity_main.xml 其实实现这个效果我们只需要配置布局文件即可,不需要写复杂的程序代码。接下来我们就来看一下这个神奇的布局文件,我们仍以MainActivity的activity_ma...

今天继续看AppBarLayout的一个强大功能,那就是它结合CollapsingToolbarLayout可以1分钟作出我们常用的滑动视差效果,效果图如下:

1. 布局activity_main.xml

其实实现这个效果我们只需要配置布局文件即可,不需要写复杂的程序代码。接下来我们就来看一下这个神奇的布局文件,我们仍以MainActivity的activity_main.xml布局为例:


  
  1. <android.support.design.widget.CoordinatorLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <android.support.v4.widget.NestedScrollView
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. app:layout_behavior="@string/appbar_scrolling_view_behavior" >
  12. <LinearLayout
  13. android:orientation="vertical"
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent" >
  16. <android.support.v7.widget.CardView
  17. android:layout_width="300dp"
  18. android:layout_height="200dp"
  19. android:layout_margin="0dp"
  20. app:cardCornerRadius="20dp"
  21. app:cardElevation="10dp"
  22. app:contentPadding="5dp" >
  23. <ImageView
  24. android:layout_width="match_parent"
  25. android:layout_height="wrap_content"
  26. android:scaleType="centerCrop"
  27. android:src="@drawable/image2" />
  28. </android.support.v7.widget.CardView>
  29. <android.support.v7.widget.CardView
  30. android:layout_width="300dp"
  31. android:layout_height="200dp"
  32. android:layout_margin="0dp"
  33. app:cardCornerRadius="20dp"
  34. app:cardElevation="10dp"
  35. app:contentPadding="5dp" >
  36. <ImageView
  37. android:layout_width="match_parent"
  38. android:layout_height="wrap_content"
  39. android:scaleType="centerCrop"
  40. android:src="@drawable/image2" />
  41. </android.support.v7.widget.CardView>
  42. <android.support.v7.widget.CardView
  43. android:layout_width="300dp"
  44. android:layout_height="200dp"
  45. android:layout_margin="0dp"
  46. app:cardCornerRadius="20dp"
  47. app:cardElevation="10dp"
  48. app:contentPadding="5dp" >
  49. <ImageView
  50. android:layout_width="match_parent"
  51. android:layout_height="wrap_content"
  52. android:scaleType="centerCrop"
  53. android:src="@drawable/image2" />
  54. </android.support.v7.widget.CardView>
  55. <android.support.v7.widget.CardView
  56. android:layout_width="300dp"
  57. android:layout_height="200dp"
  58. android:layout_margin="0dp"
  59. app:cardCornerRadius="20dp"
  60. app:cardElevation="10dp"
  61. app:contentPadding="5dp" >
  62. <ImageView
  63. android:layout_width="match_parent"
  64. android:layout_height="wrap_content"
  65. android:scaleType="centerCrop"
  66. android:src="@drawable/image2" />
  67. </android.support.v7.widget.CardView>
  68. <android.support.v7.widget.CardView
  69. android:layout_width="300dp"
  70. android:layout_height="200dp"
  71. android:layout_margin="0dp"
  72. app:cardCornerRadius="20dp"
  73. app:cardElevation="10dp"
  74. app:contentPadding="5dp" >
  75. <ImageView
  76. android:layout_width="match_parent"
  77. android:layout_height="wrap_content"
  78. android:scaleType="centerCrop"
  79. android:src="@drawable/image2" />
  80. </android.support.v7.widget.CardView>
  81. <android.support.v7.widget.CardView
  82. android:layout_width="300dp"
  83. android:layout_height="200dp"
  84. android:layout_margin="0dp"
  85. app:cardCornerRadius="20dp"
  86. app:cardElevation="10dp"
  87. app:contentPadding="5dp" >
  88. <ImageView
  89. android:layout_width="match_parent"
  90. android:layout_height="wrap_content"
  91. android:scaleType="centerCrop"
  92. android:src="@drawable/image2" />
  93. </android.support.v7.widget.CardView>
  94. <android.support.v7.widget.CardView
  95. android:layout_width="300dp"
  96. android:layout_height="200dp"
  97. android:layout_margin="0dp"
  98. app:cardCornerRadius="20dp"
  99. app:cardElevation="10dp"
  100. app:contentPadding="5dp" >
  101. <ImageView
  102. android:layout_width="match_parent"
  103. android:layout_height="wrap_content"
  104. android:scaleType="centerCrop"
  105. android:src="@drawable/image" />
  106. </android.support.v7.widget.CardView>
  107. </LinearLayout>
  108. </android.support.v4.widget.NestedScrollView>
  109. <android.support.design.widget.AppBarLayout
  110. android:layout_width="match_parent"
  111. android:layout_height="256dp"
  112. android:fitsSystemWindows="true">
  113. <android.support.design.widget.CollapsingToolbarLayout
  114. android:id="@+id/collapsing_toolbar_layout"
  115. android:layout_width="match_parent"
  116. android:layout_height="match_parent"
  117. app:contentScrim="#30469b"
  118. app:expandedTitleMarginBottom="100dp"
  119. app:expandedTitleMarginStart="100dp"
  120. app:layout_scrollFlags="scroll|exitUntilCollapsed">
  121. <ImageView
  122. android:layout_width="match_parent"
  123. android:layout_height="match_parent"
  124. android:scaleType="centerCrop"
  125. android:src="@drawable/image"
  126. app:layout_collapseMode="parallax"
  127. app:layout_collapseParallaxMultiplier="0.7" />
  128. <android.support.v7.widget.Toolbar
  129. android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
  130. app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
  131. android:id="@+id/toolbar"
  132. android:layout_width="match_parent"
  133. android:layout_height="?attr/actionBarSize"
  134. app:layout_collapseMode="pin" />
  135. </android.support.design.widget.CollapsingToolbarLayout>
  136. </android.support.design.widget.AppBarLayout>
  137. </android.support.design.widget.CoordinatorLayout>

 实现了这个效果的过程是这样的:当我们上滑NestedScrollView的时候,AppBarLayout会控制CollapsingToolbarLayout不断让Imageview折叠,直到Toolbar的底部停止。在折叠的时候滑动界面往上移动的速度>Imageview折叠的速度,从而形成了视差效果。我们要为这些控件配置一些属性才能使它们相互配合起来。

1.1  NestedScrollView控件配置: 

      滑动部分,里面内嵌了足够长的控件(Cardview),与Scrollview一样可以滑动;

(1)app:layout_behavior="@string/appbar_scrolling_view_behavior属性:

        配置了app:layout_behavior="@string/appbar_scrolling_view_behavior属性,也就是指定了behavior,behavior用来捕获  NestedScrollView的滑动事件,并处理一些动画效果。这个behavior我们从名字来看它的来头不小,它正是AppbarLayout的一个内部类behavior.所以推测它可以处理appBarLayout内部包含的控件的动画效果,即我们的折叠视差效果。NestedScrollView控件所配置的behavior就是用来控制AppBarLayout内嵌的这个CollapsingToolbarLayout控件的行为,即让CollapsingToolbarLayout内嵌的折叠布局,这里是一张图片与NestedScrollView的滚动形成视差效果。

1.2 CollapsingToolbarLayout(折叠控件)控件配置:

 它里面嵌套了视差图片Imageview与Toolbar控件。它控制内嵌的Imageview的滑动视差效果。在这个例子中配置了如下属性:

 

 (1)app:contentScrim="#30469b"

        这个用以表示当滑动快到Toolbar的底部边缘时,正在滑动的imageview消失变成了一个色块布局,同时Toolbar的颜色也会            变成相同的颜色,这里是蓝色。

(2)app:expandedTitleMarginBottom="100dp",app:expandedTitleMarginStart="100dp"


       CollapsingToolbarLayout处于展开状态时,CollapsingToolbarLayout布局中的title的位置,距离CollapsingToolbarLayout的左边距是100dp,底部边距也是100dp。关于这个title的文本我们用程序代码去设置,见后面的MainActivity分析,当然我们也可以在CollapsingToolbarLayout XML标签里配置title文本.

(3)app:layout_scrollFlags="scroll|exitUntilCollapsed"

       这个属性决定了折叠动作。让内嵌的折叠布局(Imageivew)可以滑动,直到折叠效果完成(滑动到Toolbar的底边缘)隐藏Imageview. 在这里我们只看到了滑动,和什么时候隐藏,我们并没有看到任何关于视差效果的配置。视差效果的配置是在折叠布局里设置的,在这个例子中是一个Imageview。接下来我们就来看一下Imageview(折叠布局)是如何配置的。

1.3  折叠内容配置(这里是一个Imageview图片):

(1)app:layout_collapseMode="parallax" 这个用于配置折叠隐藏的速度。

      app:layout_collapseParallaxMultiplier="0.7" 这个是视差系数,就是折叠的速度。值越大Imagview折叠的速度越快,例如配置成2的效果是:当NestedScrollView还没有滑动到Toolbar附近,离Toolbar还有好长一段距离时,这时Imageview已经往下移动了好大一截,快要完全隐藏折叠的节奏。这里我们解释了Imageview如何配置成视差效果,我们再看看Toolbar配置了什么。

1.4  Toolbar的配置:


  
  1. app:layout_collapseMode="pin"
  2.   表示当完全折叠时,Toolbar保持在顶端不动。

 

1. 5  总结

好了我们来总结一下这些配置,以便我们在后面修改这些配置来演示其它效果:

NestedScrollView

      app:layout_behavior="@string/appbar_scrolling_view_behavior  //behavior

CollapsingToolbarLayout:

      app:contentScrim="#30469b"        //Toolbar及底部附近的颜色。

      app:expandedTitleMarginBottom="100dp",      app:expandedTitleMarginStart="100dp" //下边距,左边距。

      app:layout_scrollFlags="scroll|exitUntilCollapsed"  //滚动且折叠完后整个折叠布局才隐藏。

Imageview:

  app:layout_collapseMode="parallax"     //这个就是视差效果。 app:layout_collapseParallaxMultiplier="0.7" 折叠布局折叠的速度。

2. MainActivity.java

第1节中activity_main.xml对应的程序代码


  
  1. package com.example.administrator.collapsingtoolbarlayout;
  2. import android.graphics.Color;
  3. import android.support.design.widget.CollapsingToolbarLayout;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.support.v7.widget.Toolbar;
  7. import android.view.View;
  8. public class MainActivity extends AppCompatActivity {
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13. //Toolbar
  14. Toolbar toolbar;
  15. toolbar = (Toolbar)findViewById(R.id.toolbar);
  16. setSupportActionBar(toolbar);
  17. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  18. toolbar.setNavigationOnClickListener(new View.OnClickListener() {
  19. @Override
  20. public void onClick(View v) {
  21. onBackPressed();
  22. }
  23. });
  24. /*
  25. CollapsingToolbarLayout
  26. 使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上
  27. 扩展title与折叠title会从白色随着滑动折叠自然过渡到绿色
  28. */
  29. CollapsingToolbarLayout mCollapsingToolbarLayout =
  30. (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
  31. mCollapsingToolbarLayout.setTitle("周星驰");
  32. //通过CollapsingToolbarLayout修改字体颜色
  33. mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
  34. mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);//设置收缩后Toolbar上字体的颜色
  35. }
  36. }

再上述代码里我们用代码 

mCollapsingToolbarLayout.setTitle("Colla");设置了CollapsingToolbarLayout布局在展开时的标题文本。
 

  
  1. setExpandedTitleColor与setCollapsedTitleTextColor分别设置了展开时与折叠时标题颜色的变化。
  2. 这里它不会突然从白色变成绿色,而是有一个渐变的过程。在此你可能会想到是不是title也被分为展开时标题和折叠时文本,
  3. 两个文本可以设置不同的内容,关于这些尝试性的改动及运行效果我们将在第3节中展示,第3节也会让您加深对各属性的理解。
  4. 关于本文的第3节今日恐怕是没有时间了,以后再完善之。

依照惯例,还是给出当前阶段的源码下载地址:https://download.csdn.net/download/gaoxiaoweiandy/10973541

 

附录:

使用心得

这个app:layout_behavior="@string/appbar_scrolling_view_behavior" 其实就是

AppBarLayout.ScrollingViewBehavior类。
 

我们完全可以自定义Behavior,让其继承AppBarLayout.ScrollingViewBehavior,关于自定义behavior将在后面两篇文章讲解。这里贴出一个继承代码:


  
  1. package com.example.administrator.collapsingtoolbarlayout;
  2. import android.content.Context;
  3. import android.support.annotation.NonNull;
  4. import android.support.design.widget.AppBarLayout;
  5. import android.support.design.widget.CoordinatorLayout;
  6. import android.support.v4.view.ViewCompat;
  7. import android.util.AttributeSet;
  8. import android.util.Log;
  9. import android.view.View;
  10. import android.widget.Button;
  11. public class MyBehavior extends AppBarLayout.ScrollingViewBehavior {
  12. public MyBehavior(Context arg0, AttributeSet arg1) {
  13. super(arg0, arg1);
  14. // TODO Auto-generated constructor stub
  15. }
  16. @Override
  17. public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
  18. return (axes == ViewCompat.SCROLL_AXIS_VERTICAL)||super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
  19. target, axes);
  20. }
  21. @Override
  22. public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
  23. Button btTest = coordinatorLayout.findViewById(R.id.btTest);
  24. Log.i("onNestedPreScroll","dy="+dy);
  25. if(dy > 20)
  26. {
  27. int color = coordinatorLayout.getContext().getResources().getColor(R.color.white);
  28. btTest.setBackground(null);
  29. btTest.setTextColor(color);
  30. }
  31. else if(dy < -20)
  32. {
  33. int color = coordinatorLayout.getContext().getResources().getColor(R.color.colorAccent);
  34. btTest.setBackground(null);
  35. btTest.setTextColor(color);
  36. }
  37. super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
  38. }
  39. }

这里是用于监听滑动事件的,其中以下代码表示监听垂直方向VERITCAL上的滑动。


  
  1.     return (axes == ViewCompat.SCROLL_AXIS_VERTICAL)||super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
  2.                 target, axes);

然后在onNestedPreScroll里对按钮btTest做了处理:改变颜色;同时AppBarLayout.ScrollingViewBehavior本身就自带了很多功能,结合折叠控件CollapsingToolbarLayout可以作出折叠视差效果,就是本篇所讲的视差效果。

 

2. 其它

发现一个demo里floatingActionButton里设置了这样一个属性

app:layout_anchor="@id/appbar"

app:layout_anchorGravity="bottom|right"

表示floatingActionButton与appbar关联在一起,并且浮动在appbar的右下角。

 

 

 

 

 

 

 

 

 

 

文章来源: blog.csdn.net,作者:冉航--小虾米,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/gaoxiaoweiandy/article/details/87907558

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。