Android UI Material Design交互设计(六)--CoordinatorLayout之精髓Behavior 自定义Behavior

Material Design 交互设计在Android上的应用,Design Support Library 是在2015年
Google官方发布的一个全新兼容函数库,它使得开发这可以在Android2.1(API
7)及以上的设备中实现交互设计的效果。这个函数库提供了一些了的控件,主要包括:Snackbar
、NavigationView、FloatingActionButton、TextInputLayout、TabLayout、CollapsingToolbarLayout、AppBarLayout、CoordinatorLayout

Android UI Material Design交互设计(一)–BottomNavigationView底部菜单
Android UI Material Design交互设计(二)–Toolbar的基本使用与样式修改
Android UI Material Design交互设计(三)–SnackBar 详解
Android UI Material Design交互设计(四)–AppBarLayout 与Toolbar结合
Android UI Material Design交互设计(五)–CollapsingToolbarLayout 折叠布局

在使用Design Support Library之前,首先需要添加如下依赖

implementation 'com.android.support:design:28.0.0'

惯例先上效果图: 看中间的浮动按钮
在这里插入图片描述
怎么实现呢?
第一步:布局中的根布局为CoordinatorLayout

第二步:给listview 或者 NestedScrollView 等滑动的控件或者其父控件加上
app:layout_behavior="@string/appbar_scrolling_view_behavior"属性,让

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

        。。。。。。

第三步:给FloatingActionButton浮动按钮添加自定义Behavior

app:layout_behavior=“com.goodboy.mile.Behavior.ScaleBehavior”

<android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        android:id="@+id/float_action_button"
        android:layout_gravity="center"
        app:srcCompat="@android:drawable/ic_dialog_email"
        app:layout_behavior="com.goodboy.mile.Behavior.ScaleBehavior"/>

ScaleBehavior是自定义Behavior,继承自CoordinatorLayout.Behavior。
CoordinatorLayout的强大就源于Behavior,Behavior可以让CoordinatorLayout与其子控件实现各种炫酷的交互效果。下面开始撸代码,看看怎么实现自定义Behavior。
代码如下:


public class ScaleBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {



    private FastOutLinearInInterpolator mFastOutLinearInInterpolator = new FastOutLinearInInterpolator();
    private LinearOutSlowInInterpolator mLinearOutSlowInInterpolator = new LinearOutSlowInInterpolator();

    public ScaleBehavior() {
    }

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

    private boolean isRunning;

    //重写嵌套滑动开始
    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        return axes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    //重写嵌套滑动进行中 来监听CoordinatorLayout子view的滑动事件,我们可以在这里判断浮动按钮的消失与出现
    @Override
    public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
        Log.d("ScaleBehavior","dyConsumed:"+dyConsumed);
        if (dyConsumed > 0 && !isRunning && child.getVisibility() == View.VISIBLE){//向下滑动,缩放隐藏控件
            scaleHide(child);
        }else if (dyConsumed < 0 && !isRunning && child.getVisibility() == View.INVISIBLE){//向上滑动缩放显示控件
            scaleShow(child);
        }
    }

    //浮动按钮显示动画
    private void scaleShow(V child) {
        Log.d("ScaleBehavior","scale behavior scaleShow");
        child.setVisibility(View.VISIBLE);
        ViewCompat.animate(child)
                .scaleX(1)
                .scaleY(1)
                .setDuration(500)
                .setInterpolator(mLinearOutSlowInInterpolator)
                .setListener(new ViewPropertyAnimatorListenerAdapter(){
                    @Override
                    public void onAnimationStart(View view) {
                        super.onAnimationStart(view);
                        isRunning = true;
                    }

                    @Override
                    public void onAnimationEnd(View view) {
                        super.onAnimationEnd(view);
                        isRunning = false;
                    }

                    @Override
                    public void onAnimationCancel(View view) {
                        super.onAnimationCancel(view);
                        isRunning = false;
                    }
                });
    }
    //浮动按钮隐藏动画
    private void scaleHide(final V child) {
        Log.d("ScaleBehavior","scale behavior scaleHide");
        ViewCompat.animate(child)
                .scaleX(0)
                .scaleY(0)
                .setDuration(500)
                .setInterpolator(mFastOutLinearInInterpolator)
                .setListener(new ViewPropertyAnimatorListenerAdapter(){
                    @Override
                    public void onAnimationStart(View view) {
                        super.onAnimationStart(view);
                        isRunning = true;
                    }

                    @Override
                    public void onAnimationEnd(View view) {
                        super.onAnimationEnd(view);
                        isRunning = false;
                        child.setVisibility(View.INVISIBLE);
                    }

                    @Override
                    public void onAnimationCancel(View view) {
                        super.onAnimationCancel(view);
                        isRunning = false;
                    }
                });
    }
}

⚠️ 注意我们自定义Behavior时候注意重写的几个方法:

onStartNestedScroll() :嵌套滑动开始,开始滑动的时候调用一次,手松开的时候调用一次返回true代表获取滑动事件,其他的scroll事件就会被触发

onNestedScroll():嵌套滑动进行中

onNestedScrollAccepted():接受到触摸事件的时候调用

onStopNestedScroll():嵌套滑动结束

onNestedPreScroll():嵌套滑动前

onNestedFling() : Fling是“猛扔”的意思 就是快速滑动,手指已经离开屏幕来,但是还有惯性滑动的时候调用。

onNestedPreFling():要监听的子View快速滑动前调用

onInterceptTouchEvent():是否拦截触摸事件

onTouchEvent():处理触摸事件

layoutDependsOn:重写这个方法来确定依赖关系,上面例子的NestedScrollView与浮动按钮就是依赖关系,该方法返回为true就会调用onDependentViewChanged方法

onDependentViewChanged():当被依赖的View状态改变时回调

onDependentViewRemoved():当被依赖的View移除时回调

onLayoutChild:字面意思,绘制子布局时候调用

onMeasureChild():测量使用Behavior的View尺寸

⚠️我们可以通过重写以上方法来实现各种炫酷的交互特效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值