关于support design包中behaviour的使用

谷歌新推出的support design包真的是个不错的东西,它能让大家十分轻松的实现MD风格的APP,具体关于这个包的使用,很多大牛都有写过文章,我这里推荐一篇:http://blog.csdn.net/eclipsexys/article/details/46349721


这个包中我觉得最关键的一个组件就是CoordinatorLayout,而CoordinatorLayout要配合behaviour来使用才会有好的效果。behaviour具体的作用就是用来控制CoordinatorLayout中一个子控件的行为,比如一个RecyclerView底部有一个FloatingActionButton,当滑动的时候,这个FloatingActionButton要适当的出现和消失,这就要靠behaviour来控制了。下面是谷歌官方的文档,大家可以参考一下,其实还挺简单的,对照着英文应该都能看懂。

https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.Behavior.html

下面我就上一个我自定义的behaviour,是关于前面提到的FloatingActionButton的出现和消失的。具体使用方法就是在XML中定义。

<android.support.design.widget.FloatingActionButton
        android:id="@+id/FAB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="0dp"
        app:borderWidth="0dp"
        app:layout_anchor="@id/main_content"
        app:layout_anchorGravity="bottom|right"
        app:layout_scrollFlags="scroll|enterAlways"
        app:layout_behavior="com.example.administrator.behaviourtest.FloatingActionButtonBehaviour"/>

最后一行的

app:layout_behavior="com.example.administrator.behaviourtest.FloatingActionButtonBehaviour"

就是具体的代码了。


下面是JAVA代码:

package com.example.administrator.behaviourtest;

import android.animation.Animator;
import android.content.Context;
import android.os.Build;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;

/**
 * Created by Administrator on 2015/8/21.
 */
public class FloatingActionButtonBehaviour extends CoordinatorLayout.Behavior<View> {

    private static final android.view.animation.Interpolator INTERPOLATOR =
            new FastOutSlowInInterpolator();
    private boolean mIsAnimatingOut = false;

    private int mDySinceDirectionChange;

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

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
        if (dy > 0 && mDySinceDirectionChange < 0
                || dy < 0 && mDySinceDirectionChange > 0) {
            // We detected a direction change- cancel existing animations and reset our cumulative delta Y
            child.animate().cancel();
            mDySinceDirectionChange = 0;
        }

        mDySinceDirectionChange += dy;
        System.out.println("onNestedPreScroll");
        if (mDySinceDirectionChange > child.getHeight() && child.getVisibility() == View.VISIBLE) {
            animateOut(child);
        } else if (mDySinceDirectionChange < 0 && child.getVisibility() == View.GONE) {
            animateIn(child);
        }
    }

    // Same animation that FloatingActionButton.Behavior uses to
    // hide the FAB when the AppBarLayout exits
    private void animateOut(final View button) {
        if (Build.VERSION.SDK_INT >= 14) {
            ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F)
                    .setInterpolator(INTERPOLATOR).withLayer()
                    .setListener(new ViewPropertyAnimatorListener() {
                        public void onAnimationStart(View view) {
                            FloatingActionButtonBehaviour.this.mIsAnimatingOut = true;
                        }

                        public void onAnimationCancel(View view) {
                            FloatingActionButtonBehaviour.this.mIsAnimatingOut = false;
                        }

                        public void onAnimationEnd(View view) {
                            FloatingActionButtonBehaviour.this.mIsAnimatingOut = false;
                            view.setVisibility(View.GONE);
                        }
                    }).start();
        } else {
            Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out);
            anim.setInterpolator(INTERPOLATOR);
            anim.setDuration(200L);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    FloatingActionButtonBehaviour.this.mIsAnimatingOut = true;
                }

                public void onAnimationEnd(Animation animation) {
                    FloatingActionButtonBehaviour.this.mIsAnimatingOut = false;
                    button.setVisibility(View.GONE);
                }

                @Override
                public void onAnimationRepeat(final Animation animation) {
                }
            });
            button.startAnimation(anim);
        }
    }

    // Same animation that FloatingActionButton.Behavior
    // uses to show the FAB when the AppBarLayout enters
    private void animateIn(View button) {
        button.setVisibility(View.VISIBLE);
        if (Build.VERSION.SDK_INT >= 14) {
            ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F)
                    .setInterpolator(INTERPOLATOR).withLayer().setListener(null)
                    .start();
        } else {
            Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in);
            anim.setDuration(200L);
            anim.setInterpolator(INTERPOLATOR);
            button.startAnimation(anim);
        }
    }
}



其中onStartNestedScroll是用来告诉behaviour要检测哪个方向的滑动,这里我传的是竖直方向的。

最重要的一个方法onNestedPreScroll,是用来控制滑动之后的事件的,这里我就简单的写了一下,判断y轴滑动的距离来控制button的出现和消失。

大家可以照着写一下,其实还是很简单的,但是可以实现很多不同的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值