Android高级UI开发(二十一)AppBarLayout与CollapsingToolbarLayout一分钟组合出视差效果
今天继续看AppBarLayout的一个强大功能,那就是它结合CollapsingToolbarLayout可以1分钟作出我们常用的滑动视差效果,效果图如下:
1. 布局activity_main.xml
其实实现这个效果我们只需要配置布局文件即可,不需要写复杂的程序代码。接下来我们就来看一下这个神奇的布局文件,我们仍以MainActivity的activity_main.xml布局为例:
-
<android.support.design.widget.CoordinatorLayout
-
xmlns:android="http://schemas.android.com/apk/res/android"
-
xmlns:app="http://schemas.android.com/apk/res-auto"
-
xmlns:tools="http://schemas.android.com/tools"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
tools:context=".MainActivity">
-
<android.support.v4.widget.NestedScrollView
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
-
-
<LinearLayout
-
android:orientation="vertical"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent" >
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image2" />
-
</android.support.v7.widget.CardView>
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image2" />
-
</android.support.v7.widget.CardView>
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image2" />
-
</android.support.v7.widget.CardView>
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image2" />
-
</android.support.v7.widget.CardView>
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image2" />
-
</android.support.v7.widget.CardView>
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image2" />
-
</android.support.v7.widget.CardView>
-
-
<android.support.v7.widget.CardView
-
android:layout_width="300dp"
-
android:layout_height="200dp"
-
android:layout_margin="0dp"
-
app:cardCornerRadius="20dp"
-
app:cardElevation="10dp"
-
app:contentPadding="5dp" >
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image" />
-
</android.support.v7.widget.CardView>
-
</LinearLayout>
-
</android.support.v4.widget.NestedScrollView>
-
<android.support.design.widget.AppBarLayout
-
android:layout_width="match_parent"
-
android:layout_height="256dp"
-
android:fitsSystemWindows="true">
-
<android.support.design.widget.CollapsingToolbarLayout
-
android:id="@+id/collapsing_toolbar_layout"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
app:contentScrim="#30469b"
-
app:expandedTitleMarginBottom="100dp"
-
app:expandedTitleMarginStart="100dp"
-
app:layout_scrollFlags="scroll|exitUntilCollapsed">
-
-
<ImageView
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:scaleType="centerCrop"
-
android:src="@drawable/image"
-
app:layout_collapseMode="parallax"
-
app:layout_collapseParallaxMultiplier="0.7" />
-
-
<android.support.v7.widget.Toolbar
-
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
-
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
-
android:id="@+id/toolbar"
-
android:layout_width="match_parent"
-
android:layout_height="?attr/actionBarSize"
-
app:layout_collapseMode="pin" />
-
</android.support.design.widget.CollapsingToolbarLayout>
-
</android.support.design.widget.AppBarLayout>
-
-
-
</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的配置:
-
app:layout_collapseMode="pin"
-
表示当完全折叠时,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对应的程序代码
-
package com.example.administrator.collapsingtoolbarlayout;
-
import android.graphics.Color;
-
import android.support.design.widget.CollapsingToolbarLayout;
-
import android.support.v7.app.AppCompatActivity;
-
import android.os.Bundle;
-
import android.support.v7.widget.Toolbar;
-
import android.view.View;
-
-
public class MainActivity extends AppCompatActivity {
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
-
//Toolbar
-
Toolbar toolbar;
-
toolbar = (Toolbar)findViewById(R.id.toolbar);
-
setSupportActionBar(toolbar);
-
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
-
@Override
-
public void onClick(View v) {
-
onBackPressed();
-
}
-
});
-
-
/*
-
CollapsingToolbarLayout
-
使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上
-
扩展title与折叠title会从白色随着滑动折叠自然过渡到绿色
-
*/
-
-
CollapsingToolbarLayout mCollapsingToolbarLayout =
-
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
-
mCollapsingToolbarLayout.setTitle("周星驰");
-
-
//通过CollapsingToolbarLayout修改字体颜色
-
mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
-
mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);//设置收缩后Toolbar上字体的颜色
-
}
-
}
再上述代码里我们用代码
mCollapsingToolbarLayout.setTitle("Colla");设置了CollapsingToolbarLayout布局在展开时的标题文本。
-
setExpandedTitleColor与setCollapsedTitleTextColor分别设置了展开时与折叠时标题颜色的变化。
-
这里它不会突然从白色变成绿色,而是有一个渐变的过程。在此你可能会想到是不是title也被分为展开时标题和折叠时文本,
-
两个文本可以设置不同的内容,关于这些尝试性的改动及运行效果我们将在第3节中展示,第3节也会让您加深对各属性的理解。
-
关于本文的第3节今日恐怕是没有时间了,以后再完善之。
依照惯例,还是给出当前阶段的源码下载地址:https://download.csdn.net/download/gaoxiaoweiandy/10973541
附录:
使用心得
这个app:layout_behavior="@string/appbar_scrolling_view_behavior" 其实就是
AppBarLayout.ScrollingViewBehavior类。
我们完全可以自定义Behavior,让其继承AppBarLayout.ScrollingViewBehavior,关于自定义behavior将在后面两篇文章讲解。这里贴出一个继承代码:
-
package com.example.administrator.collapsingtoolbarlayout;
-
-
import android.content.Context;
-
import android.support.annotation.NonNull;
-
import android.support.design.widget.AppBarLayout;
-
import android.support.design.widget.CoordinatorLayout;
-
import android.support.v4.view.ViewCompat;
-
import android.util.AttributeSet;
-
import android.util.Log;
-
import android.view.View;
-
import android.widget.Button;
-
-
public class MyBehavior extends AppBarLayout.ScrollingViewBehavior {
-
-
public MyBehavior(Context arg0, AttributeSet arg1) {
-
super(arg0, arg1);
-
// TODO Auto-generated constructor stub
-
}
-
@Override
-
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
-
-
return (axes == ViewCompat.SCROLL_AXIS_VERTICAL)||super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
-
target, axes);
-
-
}
-
-
@Override
-
public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
-
-
Button btTest = coordinatorLayout.findViewById(R.id.btTest);
-
-
Log.i("onNestedPreScroll","dy="+dy);
-
if(dy > 20)
-
{
-
int color = coordinatorLayout.getContext().getResources().getColor(R.color.white);
-
btTest.setBackground(null);
-
btTest.setTextColor(color);
-
}
-
else if(dy < -20)
-
{
-
int color = coordinatorLayout.getContext().getResources().getColor(R.color.colorAccent);
-
btTest.setBackground(null);
-
btTest.setTextColor(color);
-
}
-
-
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
-
}
-
}
这里是用于监听滑动事件的,其中以下代码表示监听垂直方向VERITCAL上的滑动。
-
return (axes == ViewCompat.SCROLL_AXIS_VERTICAL)||super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
-
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
- 点赞
- 收藏
- 关注作者
评论(0)