需要导入依赖:
页面基本结构:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
//background为整个布局最下层的背景色,一般被上层AppBarLayout,Toolbar等覆盖
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFAFAFA"
android:fitsSystemWindows="true">
//AppBarLayout中包含了ToolBar和折叠区域的内容,其height为二者高度之和
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="140dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
//app:contentScrim表示可折叠的部分收缩之后的颜色
//app:expandedTitleXXX表示可伸缩部分展开之后的各种属性,
//其中TextAppearance需要在xml/values/style中建立xml文件,指定展开后标题的大小和颜色
//可以通过调整ToolBar和伸展部分Layout的先后关系改变覆盖关系来达到特定效果
//app:layout_scrollFlags != scroll 不可滑动
//app:layout_scrollFlags = scroll 可以将ToolBar滑至消失
//app:layout_scrollFlags = scroll|exitUntilCollapsed 可以将可收缩部分滑至消失,始终保留ToolBar
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="#FF363E4D"
app:expandedTitleGravity="start|top"
app:expandedTitleMarginStart="111dp"
app:expandedTitleMarginTop="76dp"
app:expandedTitleTextAppearance="@style/expand_title"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title="title">
//可收缩部分的layout布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginTop="56dp"
android:background="#FF363E4D"
android:orientation="horizontal"
app:layout_collapseMode="parallax">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="100dp"
android:scaleType="centerInside" />
</LinearLayout>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#FF363E4D"
android:paddingEnd="10dp"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/test"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
//直接使用ScrollView会导致拖动ScrolleView无法控制顶部伸缩
//只有在拖动AppBarLayout范围内的控件时才可以控制伸缩
//所以需要自己重写派生ScrolleView的一个子类MyNestedScrollView来使用
<MyNestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#55FFFF00"
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">
//使用重写的MyNestedScrollView而内部无任何布局仍然会导致以上ScrolleView无法控制顶部伸缩的问题
//所以记得使用一个布局填充TPNestedScrollView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
res/values/styles.xml中需要添加的style来控制伸展的标题文字大小和颜色等属性
<style name="expand_title" parent="TextAppearance.Design.Tab">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#FFFF00</item>
</style>
自己手动重写的MyNestedScrollView.class:
public class MyNestedScrollView extends NestedScrollView {
public boolean isFling = false;
private OverScroller mScroller;
public MyNestedScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = getOverScroller();
}
private OverScroller getOverScroller() {
Field fs;
try {
fs = this.getClass().getSuperclass().getDeclaredField("mScroller");
fs.setAccessible(true);
return (OverScroller) fs.get(this);
} catch (Throwable t) {
return null;
}
}
@Override
protected void onScrollChanged(int l, final int t, final int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (isFling) {
if (Math.abs(t - oldt) <= 3 || t == 0 ||
t == (getChildAt(0).getMeasuredHeight() - getMeasuredHeight())) {
isFling = false;
if (mScroller != null) {
mScroller.abortAnimation();
}
}
}
}
@Override
public void fling(int velocityY) {
super.fling(velocityY);
if (getChildCount() > 0) {
ViewCompat.postInvalidateOnAnimation(this);
isFling = true;
}
}
}
此时就完成了一个页面的推拉折叠效果。