This page looks best with JavaScript enabled

CoordinatorLayout Behavior

 ·  ☕ 2 min read

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 = " "
    }
}

Yang
WRITTEN BY
Yang
Developer