近年来,越来越多的类似博客主页页面 顶部背景图搭配文字出现各种各样的效果,例如顶部悬浮,背景色变换 文字移动,控件移动等效果,原先 使用CoordinatorLayout 控件监听 移动变化然后再给各个控件设置动画以及属性,来完成实现效果
MotionLayout 出现后更方便控制各个动画的联动,处理多个动画以及属性的协调变化更舒畅,更方便的实现这种页面的效果.
期望:类似博客首页 伴随滑动实现如下效果
- 头像北京渐变透明,
- 文字旋转90°
- 指定宽度悬浮
1. Layout.xml布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
android:background="@color/white"
android:fitsSystemWindows="false">
<!-- 顶部布局 -->
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_layout"
android:layout_width="match_parent"
android:layout_height="300dp">
<!-- minHeight: 最小高度 -->
<!-- background: 背景色 -->
<!-- layoutDescription : 配置文件-->
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/ml"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:fitsSystemWindows="false"
android:minHeight="60dp"
android:theme="@style/AppTheme.AppBarOverlay"
app:layoutDescription="@xml/scene_coordinator_layout01"
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
tools:ignore="MotionLayoutInvalidSceneFileReference">
<ImageView
android:id="@+id/backgroundIcon"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@mipmap/roard" />
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试文字,旋转了90°"
android:textColor="#FFF"
android:textSize="16dp"
android:transformPivotX="0dp"
android:transformPivotY="0dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</com.google.android.material.appbar.AppBarLayout>
<!-- 移动的控件 -->
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollable"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="@string/large_text" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
2. MotionScene scene_coordinator_layout01.xml布局
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:motionInterpolator="linear"></Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/backgroundIcon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="1.0"
motion:layout_constraintBottom_toBottomOf="parent">
</Constraint>
<Constraint
android:layout_marginLeft="20dp"
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="-90.0"
android:layout_marginStart="18dp"
android:layout_marginBottom="18dp"
motion:layout_constraintBottom_toBottomOf="@+id/backgroundIcon"
motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@id/backgroundIcon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.2"
motion:layout_constraintBottom_toBottomOf="parent"></Constraint>
<Constraint
android:id="@id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginBottom="18dp"
android:rotation="0.0"
motion:layout_constraintBottom_toBottomOf="@+id/backgroundIcon"
motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
</MotionScene>
3.代码
package com.wu.material
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.motion.widget.MotionLayout
import com.google.android.material.appbar.AppBarLayout
/**
* @author wkq
*
* @date 2022年01月24日 13:56
*
*@des
*
*/
class CoordinatorLayoutActivity : AppCompatActivity() {
@SuppressLint("RestrictedApi")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mothion_coordinator_layout)
//显示路径
var motionLayout = findViewById<MotionLayout>(R.id.ml)
motionLayout.setDebugMode(MotionLayout.DEBUG_SHOW_PATH)
var appBarLayout = findViewById<AppBarLayout>(R.id.app_layout)
appBarLayout.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
//绑定 MotionLayout偏移量
motionLayout.progress = -verticalOffset / appBarLayout?.totalScrollRange?.toFloat()!!
}
})
}
}
总结
实现了博客页面一些常见的联动动画,代码简单 执行流畅.要实现博客页面面的需求可以参考这种实现方式