美文网首页
Android kotlin CoordinatorLayout

Android kotlin CoordinatorLayout

作者: 水天滑稽天照八野滑稽石 | 来源:发表于2020-08-11 02:48 被阅读0次

Android kotlin CoordinatorLayout使用笔记(一)
Android kotlin CoordinatorLayout使用笔记(二)
Android kotlin CoordinatorLayout使用笔记(三)

前言

这篇是前面3个所讲的一个综合应用和补全

先来看下我们实现的效果


可以看到有如下效果:

  • Toobar的折叠
  • 头像的放大缩小及移动
  • 背景图的渐变消失

直接上代码

<?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"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/ly_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior=".BgBehavior">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/ly_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:expandedTitleMarginBottom="60dp"
            app:expandedTitleGravity="end"
            app:expandedTitleMarginEnd="40dp"
            app:title="title"
            app:collapsedTitleGravity="start">

            <ImageView
                android:id="@+id/img_bg"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="fitXY"
                android:src="@drawable/bg"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.9"/>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="46dp"
                app:titleMarginStart="40dp"
                app:layout_collapseMode="pin">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="返回"
                    android:textSize="13sp"
                    android:textColor="@android:color/white" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_gravity="right"
                    android:layout_centerHorizontal="true"
                    android:layout_marginRight="6dp"
                    android:gravity="center"
                    android:padding="4dp"
                    android:textColor="#fff"
                    android:textSize="14sp"
                    android:text="菜单"/>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:behavior_overlapTop="30dp"
        android:overScrollMode="never"
        android:scrollbars="none"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_marginLeft="40dp"
                android:layout_marginRight="40dp"
                android:layout_marginBottom="40dp"
                app:cardBackgroundColor="@android:color/white"
                app:cardElevation="3dp" />

            <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:layout_marginBottom="40dp"
            app:cardElevation="3dp"
            app:cardBackgroundColor="@android:color/white"/>

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_marginLeft="40dp"
                android:layout_marginRight="40dp"
                android:layout_marginBottom="40dp"
                app:cardElevation="3dp"
                app:cardBackgroundColor="@android:color/white"/>

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_marginLeft="40dp"
                android:layout_marginRight="40dp"
                android:layout_marginBottom="40dp"
                app:cardElevation="3dp"
                app:cardBackgroundColor="@android:color/white"/>

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_marginLeft="40dp"
                android:layout_marginRight="40dp"
                android:layout_marginBottom="40dp"
                app:cardElevation="3dp"
                app:cardBackgroundColor="@android:color/white"/>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

    <ImageView
        android:id="@+id/img_head"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_behavior=".HeadImageBehavior"
        android:layout_gravity="center_horizontal"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

BgBehavior 背景图的出现消失behavior

class BgBehavior @JvmOverloads constructor(context: Context,
                                           attrs: AttributeSet) : AppBarLayout.Behavior(context, attrs){

    override fun onLayoutChild(parent: CoordinatorLayout, abl: AppBarLayout, layoutDirection: Int): Boolean {

        val imgBg = abl.findViewById<ImageView>(R.id.img_bg)

        /**
         * 处于中心时候原始X轴
         */
        var mOriginalHeaderX = 0
        /**
         * 处于中心时候原始Y轴
         */
        var mOriginalHeaderY = 0

        abl.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
            //计算imgBg从开始移动到最后的百分比
            val offset = abs(verticalOffset).toFloat()
            var percent = offset / (appBarLayout.totalScrollRange.toFloat() * 0.7f)
            //百分大于1,直接赋值为1
            if (percent >= 1) {
                percent = 1f
            }
            val alpha = 1 - percent
            //设置透明度
            imgBg.alpha = alpha

        })

        return super.onLayoutChild(parent, abl, layoutDirection)
    }
}

代码说明

这儿使用的behavior不是CoordinatorLayout.Behavior,而是 AppBarLayout.Behavior,但在用法上是没什么差别的,这儿只要是体现另外一种写法。
可以看到这里重写了onLayoutChild方法
可以通过abl.findViewById的方法直接拿到对应的View,然后就可以对View进行协调操作了
CoordinatorLayout.Behavior也可以重写onLayoutChild方法这样玩

CollapsingToolbarLayout 属性

可以看到这儿我们又多用到了一些CollapsingToolbarLayout 属性,现在来补充说明一下

  • app:title 标题
  • app:titleMarginStart CollapsingToolbarLayout 折叠后title的偏移位置(这个是ToolBar的属性)
    同理有titleMarginEnd,titleMarginTop等
  • app:collapsedTitleGravity CollapsingToolbarLayout 展开时title的Gravity
  • app:expandedTitleMarginBottom CollapsingToolbarLayout 展开时title的偏移位置
    同理有:expandedTitleMarginTop,expandedTitleMarginStart等

NestedScrollView 的 app:behavior_overlapTop属性

NestedScrollView向上偏移了30dp就是这个属性的效果


HeadImageBehavior

头像位置变化及放大缩小的behavior

class HeadImageBehavior @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : CoordinatorLayout.Behavior<ImageView>(context, attrs) {

    /**
     * 处于中心时候原始X轴
     */
    private var mOriginalHeaderX = 0

    /**
     * 处于中心时候原始Y轴
     */
    private var mOriginalHeaderY = 0

    override fun layoutDependsOn(
        parent: CoordinatorLayout,
        child: ImageView,
        dependency: View
    ): Boolean {
        return dependency is AppBarLayout
    }

    override fun onDependentViewChanged(
        parent: CoordinatorLayout,
        child: ImageView,
        dependency: View
    ): Boolean {
        // 计算X轴坐标
        if (mOriginalHeaderX == 0) {
            this.mOriginalHeaderX = (dependency.width / 2) - (child.width / 2)
        }
        // 计算Y轴坐标
        if (mOriginalHeaderY == 0) {
            mOriginalHeaderY = dependency.height - child.height;
        }

        //X轴百分比
        var mPercentX: Float = Math.abs(dependency.y / mOriginalHeaderX)
        if (mPercentX >= 1) {
            mPercentX = 1f
        }

        var x = mOriginalHeaderX + mOriginalHeaderX * mPercentX
        if (x >= dependency.width - child.width * 2) {
            x = (dependency.width - child.width * 2).toFloat()
        }

        //Y轴百分比
        var mPercentY: Float = Math.abs(dependency.y / mOriginalHeaderY)
        if (mPercentY >= 1) {
            mPercentY = 1f
        }
        var y = mOriginalHeaderY - mOriginalHeaderY * mPercentY

        // 调整位置
        child.x = x
        child.y = y

        // 放大缩小
        child.scaleX = 1 - mPercentY
        child.scaleY = 1 - mPercentY
        return true
    }

}

相关文章

网友评论

      本文标题:Android kotlin CoordinatorLayout

      本文链接:https://www.haomeiwen.com/subject/ulhddktx.html