废话不多说,直接上代码,xml布局如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
android:background="@color/color_ffffff">
<!--互动详情页面布局-->
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_f1f1f6"
android:stateListAnimator="@null"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_behavior=".view.FlingBehavior">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?actionBarSize"
app:contentScrim="@color/color_ffffff"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<!-- 背景图 -->
<ImageView
android:id="@+id/ivBackGround"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/bg_lesson"
app:layout_collapseMode="parallax" />
<!-- 内容 -->
<LinearLayout
android:id="@+id/llTitleContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/s_50dp"
android:orientation="vertical"
app:layout_collapseMode="parallax">
<!--app:layout_collapseParallaxMultiplier="0.7"-->
<TextView
android:id="@+id/tvDetailName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/s_15dp"
android:layout_marginRight="@dimen/s_15dp"
android:lineSpacingExtra="@dimen/s_4dp"
android:text="@string/str_place_holder"
android:textColor="@color/color_333333"
android:textSize="@dimen/s_18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvClassName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/s_15dp"
android:layout_marginTop="@dimen/s_12dp"
android:layout_marginRight="@dimen/s_15dp"
android:text="@string/str_place_holder"
android:textColor="@color/color_666666"
android:textSize="@dimen/s_14sp"
android:textStyle="normal" />
<!--str_release_class-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/s_15dp"
android:layout_marginRight="@dimen/s_15dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvAccessCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_place_holder"
android:textColor="@color/color_666666"
android:textSize="@dimen/s_14sp"
android:textStyle="normal" />
<!--str_assess_code-->
<TextView
android:id="@+id/tvCopyAccessCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/s_15sp"
android:paddingTop="@dimen/s_12dp"
android:paddingRight="@dimen/s_15sp"
android:paddingBottom="@dimen/s_12dp"
android:text="复制"
android:textColor="@color/color_2b96ff"
android:textSize="@dimen/s_14sp" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/s_15dp"
android:layout_marginRight="@dimen/s_15dp"
android:layout_marginBottom="@dimen/s_20dp">
<TextView
android:id="@+id/tvAccessMemberCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="0"
android:textColor="@color/color_ff9100"
android:textSize="@dimen/s_20sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/tvAccessMemberCount"
android:layout_toRightOf="@+id/tvAccessMemberCount"
android:text="人参与"
android:textColor="@color/color_666666"
android:textSize="@dimen/s_14sp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvAccessMemberList"
android:layout_width="wrap_content"
android:layout_height="@dimen/s_28dp"
android:layout_alignParentRight="true" />
</RelativeLayout>
<!--脚下的圆角占位布局-->
<View
android:layout_width="match_parent"
android:layout_height="@dimen/s_10dp"
android:background="@drawable/shape_ffffff_top_left_right_5dp" />
</LinearLayout>
<!-- 一级标题 -->
<android.support.v7.widget.Toolbar
android:id="@+id/tbFirstTitle"
android:layout_width="match_parent"
android:layout_height="@dimen/s_44dp"
android:background="@android:color/transparent"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/s_44dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/ivBack"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="@dimen/s_15dp"
android:paddingRight="@dimen/s_15dp"
android:src="@drawable/nav_btn_back" />
<TextView
android:id="@+id/tvTitle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/color_333333"
android:textSize="@dimen/s_18sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/ivShare"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="@dimen/s_15dp"
android:paddingRight="@dimen/s_15dp"
android:src="@drawable/lesson_share_selector"
android:visibility="invisible" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
<!-- 二级标题 -->
<RelativeLayout
android:id="@+id/rlSecondTitle"
android:layout_width="match_parent"
android:layout_height="@dimen/s_44dp"
android:layout_gravity="bottom"
android:background="@color/color_ffffff">
<TextView
android:id="@+id/tvCourseSummary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/s_15dp"
android:text="课程小节"
android:textColor="@color/color_333333"
android:textSize="@dimen/s_16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/tvCourseSummary"
android:text="@string/str_place_holder"
android:textColor="@color/color_999999"
android:textSize="@dimen/s_14sp" />
</RelativeLayout>
</android.support.design.widget.AppBarLayout>
<!--单个item布局:layout_interactive_detail_first_item-->
<!--单个item布局:layout_interactive_detail_second_item-->
<android.support.v7.widget.RecyclerView
android:id="@+id/rvContentList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="true"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<TextView
android:id="@+id/tvContentEmpty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:drawableTop="@drawable/balnk_file"
android:drawablePadding="@dimen/s_13dp"
android:enabled="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_horizontal"
android:nestedScrollingEnabled="true"
android:paddingTop="@dimen/s_50dp"
android:paddingBottom="@dimen/s_50dp"
android:text="暂无内容"
android:textColor="@color/color_bbbbbb"
android:textSize="@dimen/s_15sp"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
效果图如下:
需要针对RecyclerView添加滚动监听器,当RecyclerView停下来的时候判定它距离屏幕顶部的高度,然后让appBarLayout执行展开或者收起,这样就能够规避掉RecyclerView和CoordinatorLayout组合发生抖动之后卡住不动的问题,具体代码如下:
// 添加顶部滑动监听器
if (appBarOffsetListener == null) {
appBarOffsetListener = new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (llTitleContent != null && tvTitle != null) {
if (verticalOffset <= -llTitleContent.getHeight() / 2) {
tvTitle.setText("互动课程详情");
} else {
tvTitle.setText("");
}
}
}
};
}
// 头条发生拖动时,需要变换主标题
appBarLayout.addOnOffsetChangedListener(appBarOffsetListener);
// 设置内容滚动监听器
if (scrollListener == null) {
scrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// 如果当前处于空闲状态,那么可以执行判定操作
if (newState == RecyclerView.SCROLL_STATE_IDLE && rvContentList != null) {
int[] location = new int[2];
rvContentList.getLocationInWindow(location);
// 两个标题栏的高度(一级标题和二级标题的高度) 加上 状态栏的高度就是recyclerView距离屏幕顶部可能到达最近的距离
float minY = titleHeight * 2 + statusHeight;
// 如果当前recyclerView距离最高位置小于5个像素,那么认为应该关闭,否则打开
if (location[1] - minY <= 5) {
if (appBarLayout != null) {
appBarLayout.setExpanded(false, true);
}
}
// 否则打开整体布局
else if (appBarLayout != null) {
appBarLayout.setExpanded(true, true);
}
}
}
};
}
// 添加滚动监听器,防止卡顿的发生
rvContentList.addOnScrollListener(scrollListener);
下面这个FlingBehavior 主要用于解决RecyclerView滑动之后,第一次点击发生失效的问题
import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
/**
* 用于解决CoordinatorLayout与RecyclerView之间发生的点击问题
*/
public class FlingBehavior extends AppBarLayout.Behavior {
public FlingBehavior() {
}
public FlingBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
stopNestedScrollIfNeeded(dyUnconsumed, child, target, type);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
stopNestedScrollIfNeeded(dy, child, target, type);
}
private void stopNestedScrollIfNeeded(int dy, AppBarLayout child, View target, int type) {
if (type == ViewCompat.TYPE_NON_TOUCH) {
final int currOffset = getTopAndBottomOffset();
if ((dy < 0 && currOffset == 0) || (dy > 0 && currOffset == -child.getTotalScrollRange())) {
ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH);
}
}
}
}