今天继续看AppBarLayout的一个强大功能,那就是它结合CollapsingToolbarLayout可以1分钟作出我们常用的滑动视差效果,效果图如下:
其实实现这个效果我们只需要配置布局文件即可,不需要写复杂的程序代码。接下来我们就来看一下这个神奇的布局文件,我们仍以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折叠的速度,从而形成了视差效果。我们要为这些控件配置一些属性才能使它们相互配合起来。
滑动部分,里面内嵌了足够长的控件(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的滚动形成视差效果。
它里面嵌套了视差图片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)app:layout_collapseMode="parallax" 这个用于配置折叠隐藏的速度。
app:layout_collapseParallaxMultiplier="0.7" 这个是视差系数,就是折叠的速度。值越大Imagview折叠的速度越快,例如配置成2的效果是:当NestedScrollView还没有滑动到Toolbar附近,离Toolbar还有好长一段距离时,这时Imageview已经往下移动了好大一截,快要完全隐藏折叠的节奏。这里我们解释了Imageview如何配置成视差效果,我们再看看Toolbar配置了什么。
app:layout_collapseMode="pin"
表示当完全折叠时,Toolbar保持在顶端不动。
好了我们来总结一下这些配置,以便我们在后面修改这些配置来演示其它效果:
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" 折叠布局折叠的速度。
第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节今日恐怕是没有时间了,以后再完善之。
这个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的右下角。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章