Step1 简单介绍 CoordinatorLayout

  • 作用:协调子 View
  • 使用核心: Behavior
  • 布局属性类似 FrameLayout

    Behavior

两个概念:

Child:CoordinatorLayout 的子 View
Dependency:Child 依赖的 View

简单使用:

device-2018-08-30-233559.gif

定义 Behavior

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class SimpleBehavior(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<Button>(context, attrs) {
private val screenWidth: Int = context.resources?.displayMetrics?.widthPixels!!
override fun layoutDependsOn(parent: CoordinatorLayout, child: Button, dependency: View): Boolean {
//判断是否依赖的View
return dependency is WithFingerTextView
}
// 当依赖的 View 位置 宽高发生变化时,执行这个方法
override fun onDependentViewChanged(parent: CoordinatorLayout, child: Button, dependency: View): Boolean {
val x = screenWidth - dependency.x - child.width
// 更新 Child
setPosition(child, x.toInt(), dependency.y.toInt())
return true
}
private fun setPosition(v: View, x: Int, y: Int) {
val layoutParams: CoordinatorLayout.LayoutParams = v.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.leftMargin = x
layoutParams.topMargin = y
v.layoutParams = layoutParams
}
}

布局中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="A Button"
app:layout_behavior="com.jy.friendcircleappbar.SimpleBehavior" />

<com.jy.friendcircleappbar.WithFingerTextView
android:id="@+id/tv"
android:layout_width="100dp"
android:layout_height="wrap"
android:layout_margin="200dp"/>
</android.support.design.widget.CoordinatorLayout>

Step2 结合 AppBarLayout CollaspsingLayout Toolbar

Toolbar 结合 AppBarLayout 才好玩

使用略过

AppBarLayout

  • 继承自 LinearLayout,垂直方向布局
  • 当某个可滚动的View滚动时,可定制它内部的子 View 实现何种动作
AppBarLayout 子 View 的动作

给子 View 设置 layout_scrollFlags 属性:

  • scroll:子 View 跟随滚动事件一起移动,类似将 View 嵌入 ScrollView
  • scroll | enterAlways:当 ScollView 向下滚动时,View 直接向下滚动。ScrollView 向上滚动时,View 也跟着上滚
  • scroll | exitUnitCollaspsed:ScrollView 向上滚动时,View 先夺去滚动事件,滚到自己的最小高度,然后 ScrollView 接着滚动。ScrollView 向下滚动时,当 ScrollView 滚动到顶部时,View 开始滚动到默认高度。
  • scroll | enterAlawys | enterAllwaysCollapsed:

通过 appbar_scrolling_view_behavior 将 NestedScrollView 和 AppBarLayout 关联。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/long_text" />
</android.support.v4.widget.NestedScrollView>

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="200dp"
android:minHeight="?android:actionBarSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

##
Step3 CollaspsingToolbarLayout

针对 Toolbar

  • 折叠 Title:当布局全部显示时 title 最大,随着上划逐步减小
    • setTitle
  • 内容纱布:根据滚动的位置到达某个阈(yu)值,决定是否为 View 覆盖纱布
    • setContentScim
  • 状态栏纱布:根据滚动的位置到达某个阈(yu)值,决定是否为状态栏覆盖纱布(5.0以上)
  • 视差滚动子View:让子View的滚动速度比其他正常滚动的慢
    • layout_collapseModel:parallax
  • 子 View 固定:Pin 模式
    • layout_collapseModel: pin

4 朋友圈 Toolbar 效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:collapsedTitleTextAppearance="@style/CollapsedAppBar"
app:contentScrim="@android:color/white"
app:expandedTitleMarginTop="8dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:statusBarScrim="@android:color/white">

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="pin">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="vertical"
android:paddingBottom="50dp">

<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitXY"
android:src="@mipmap/logo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>

<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:background="@android:color/white"
android:padding="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent">

<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@mipmap/logo" />
</FrameLayout>

</android.support.constraint.ConstraintLayout>

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="@android:color/transparent"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
app:layout_collapseMode="pin">

<ImageView
android:layout_width="48dp"
android:layout_height="24dp"
android:src="@mipmap/back" />

</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
1
2
3
4
5
6
7
8
9
collapsingToolbarLayout.title = " "
collapsingToolbarLayout.expandedTitleMarginStart = 0
appBarLayout.addOnOffsetChangedListener { appBarLayout, verticalOffset ->
if (Math.abs(verticalOffset) >= appBarLayout.totalScrollRange) {
collapsingToolbarLayout.title = "朋友圈"
} else {
collapsingToolbarLayout.title = " "
}
}