安卓behavior详解2--自定义behavior简单案例

一.前言

有时候我们要实现一些复杂效果时候,系统提供的behavior并不能完全满足我们需求,这时候使用一些自定义behavior就方便多了,比如我们要做下面这中效果

这里写图片描述

二.页面布局

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_circle_image_simple_behavior"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.testdemo.king.kingtestdemo.CircleImageSimpleBehavior">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@mipmap/holder"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.2" />

            <FrameLayout
                android:id="@+id/frameLayout"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:layout_gravity="bottom|center_horizontal"
                android:orientation="vertical"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.1">
            </FrameLayout>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:scrollbars="none"
        app:behavior_overlapTop="30dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

            <android.support.v7.widget.CardView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="8dp"
                app:cardElevation="8dp"
                app:contentPadding="16dp">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="@string/test_text" />
            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="8dp"
                app:cardElevation="8dp"
                app:contentPadding="16dp">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="@string/test_text" />
            </android.support.v7.widget.CardView>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <android.support.v7.widget.Toolbar
        android:id="@+id/mytoolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_anchor="@id/frameLayout"
        app:theme="@style/ThemeOverlay.AppCompat.Dark"></android.support.v7.widget.Toolbar>
    <!-- 第三方圆形图片控件,导入依赖即可,适用于头像处理 -->
    <ImageView
        android:id="@+id/iv_Head"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center|right"
        android:src="@mipmap/icon_caddie_unselect"
        app:layout_behavior=".behivor.CustomCircleViewBehavior" />
</android.support.design.widget.CoordinatorLayout>
  • layout_scrollFlags详解:
    • scroll:孩子视图伴随滚动事件而滚出或滚进屏幕
    • enterAlways:向下滚动时Scrolling View和Child View之间的滚动优先级,当优先滚动的一方全部滚进屏幕之后,另一方才开始滚动
    • enterAlwaysCollapsed:enterAlways的附加值,这里涉及到孩子视图的高度和最小高度,向下滚动时,孩子视图会先向下滚动至最小高度值,然后Scrolling View才开始滚动,到达边界时,孩子视图再向下滚动,直至显示完全
    • exitUtilCollapsed:这里也涉及最小高度,发生向上滚动事件时,孩子视图向上滚动退出直至最小高度,然后Scrolling View开始滚动,也就是,Child View不会完全退出屏幕
      snap:简单理解,就是Child View的一个吸附效果,也就是说,Child View不会存在局部显示的情况,滚动Child View的部分高度,当我们松开手指时,Child View 要么向上全部滚出屏幕,要么向下全部滚进屏幕,有点类似ViewPager的左右滑动
  • layout_collapseMode (折叠模式) - 有两个值:
    • pin:设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。
    • parallax:设置为这个模式时,在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用

三.自定义behavior代码实现

package com.testdemo.king.kingtestdemo.behivor;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.testdemo.king.kingtestdemo.R;

import static android.content.ContentValues.TAG;

/**
 * Created by king on 2017/9/16.
 */

public class CustomCircleViewBehavior extends CoordinatorLayout.Behavior<ImageView> {
    //圆形图片的最终大小
    private float mFinalHeadHeight = 50;
    //圆形图片起始的y坐标
    private float mStartHeadY;
    //圆形图片起始的x坐标
    private float mStartHeadX;
    //圆形图片其实的大小
    private int mOriginalHeadHeight;

    public CustomCircleViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    // 如果dependency为Toolbar
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, ImageView child, View dependency) {
//        return dependency instanceof Toolbar;
       return  dependency.getId()== R.id.mytoolbar;
    }


    //当dependency变化的时候调用
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, ImageView child, View dependency) {
//第一次执行将圆形图片其实的x,y值和圆形图片的初始大小获取到
        if (mStartHeadY == 0) {
            mStartHeadY = dependency.getY();
        }
        if (mStartHeadX == 0) {
            mStartHeadX = child.getX();
        }

        if (mOriginalHeadHeight == 0) {
            mOriginalHeadHeight = child.getHeight();
        }
//设置头像的y坐标为ToolBar的y坐标
        child.setY(dependency.getY());
//计算ToolBar移动后的y坐标占ToolBar初始y坐标的比例
        float percent = dependency.getY() / mStartHeadY;
//x坐标的目标点设置到水平中心处,按照比例让x坐标变化
        float x = -(mStartHeadX - (dependency.getWidth() / 2 - mFinalHeadHeight )) * (1 - percent) + mStartHeadX;
        Log.e(TAG, "onDependentViewChanged: "+x );
        child.setX(x);
//不断修改圆形图片的宽高(圆形图片宽度和高度一致)
        CoordinatorLayout.LayoutParams layoutParams =
                (CoordinatorLayout.LayoutParams) child.getLayoutParams();
//当前大小=最终大小+(起始大小-最终大小)x百分比
        layoutParams.height = (int) ((mOriginalHeadHeight - mFinalHeadHeight) * percent + mFinalHeadHeight);
        layoutParams.width = (int) ((mOriginalHeadHeight - mFinalHeadHeight) * percent + mFinalHeadHeight);
        child.setLayoutParams(layoutParams);

        return true;
    }
}

而这样做还有一个好处 activity没有任何的处理,实现了解耦合.

猜你喜欢

转载自blog.csdn.net/jin870132/article/details/78007505