美文网首页
FloatingActionButton设置Behavior只能

FloatingActionButton设置Behavior只能

作者: GG_Jin | 来源:发表于2017-11-02 10:08 被阅读24次

    这两天重构项目,遇到需要添加一个Fab的时候,就随便上网上copy了一段代码,测试的时候发现,只能执行一次,之后就不会走Behavior的onNestedScroll方法了。
    在网上找了半天解决办法,也没有找到。最后只能看看源码到底是因为什么吧,直接上源码

    
    @Override
    public boolean onStartNestedScroll(View child, View target, int axes, int type) {
        boolean handled = false;
    
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == View.GONE) {
                // If it's GONE, don't dispatch
                continue;
            }
            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            final Behavior viewBehavior = lp.getBehavior();
            if (viewBehavior != null) {
                final boolean accepted = viewBehavior.onStartNestedScroll(this, view, child,
                        target, axes, type);
                handled |= accepted;
                lp.setNestedScrollAccepted(type, accepted);
            } else {
                lp.setNestedScrollAccepted(type, false);
            }
        }
        return handled;
    }
    
    

    自定义的Behavior中的onStartNestedScroll方法最后会走到CoordinatorLayout方法的onStartNestedScroll方法中 在里面判断了一下childView的visibility的属性是不是GONE 是的话就会跳过

    同样的onNestedScroll中也会判断childView的属性,是GONE的时候就回跳过。所以在设置需要执行Behavior的View的属性就不要设置成GONE就可以了。

    @Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed, int type) {
        final int childCount = getChildCount();
        boolean accepted = false;
    
        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == GONE) {
                // If the child is GONE, skip...
                continue;
            }
    
            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            if (!lp.isNestedScrollAccepted(type)) {
                continue;
            }
    
            final Behavior viewBehavior = lp.getBehavior();
            if (viewBehavior != null) {
                viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
                        dxUnconsumed, dyUnconsumed, type);
                accepted = true;
            }
        }
    
        if (accepted) {
            onChildViewsChanged(EVENT_NESTED_SCROLL);
        }
    }
    
    
    

    最后附上自己写的BaseBehavior以及一个可用的Behavior

    
    open class BaseBehavior<T : View> constructor(context: Context,attrs:AttributeSet): CoordinatorLayout.Behavior<T>(){
    
        private val mFastInterpolator = FastOutSlowInInterpolator()
    
    
        // 显示view
        fun scaleShow(view: View,l :ListenerAnimatorEndBuild?) {
            view.visibility = View.VISIBLE
            ViewCompat.animate(view)
                    .scaleX(1.0f)
                    .scaleY(1.0f)
                    .alpha(1.0f)
                    .setDuration(500)
                    .setListener(l?.build())
                    .setInterpolator(mFastInterpolator)
                    .start()
        }
    
    
        // 隐藏view
        fun scaleHide(view: View,l:ListenerAnimatorEndBuild?) {
            ViewCompat.animate(view)
                    .scaleX(0.0f)
                    .scaleY(0.0f)
                    .alpha(0.0f)
                    .setDuration(500)
                    .setInterpolator(mFastInterpolator)
                    .setListener(l?.build())
                    .start()
        }
    
    
        class ListenerAnimatorEndBuild {
            // 记录View移出动画是否执行完。
            private var isOutExecute = false
    
            private val outAnimatorListener: ViewPropertyAnimatorListener
    
            // View移出动画是否执行完。
            val isFinish: Boolean
                get() = !isOutExecute
    
            init {
                outAnimatorListener = object : ViewPropertyAnimatorListener {
                    override fun onAnimationStart(view: View) {
                        isOutExecute = true
                    }
    
                    override fun onAnimationEnd(view: View) {
                        view.visibility = View.INVISIBLE
                        isOutExecute = false
                    }
    
                    override fun onAnimationCancel(view: View) {
                        isOutExecute = false
                    }
                }
            }
    
            // 返回ViewPropertyAnimatorListener。
            fun build(): ViewPropertyAnimatorListener {
                return outAnimatorListener
            }
        }
    
    }
    
    
    
    class FabBehavior constructor(context: Context, attributeSet: AttributeSet) : BaseBehavior<FloatingActionButton>(context, attributeSet) {
    
        private var  listenerAnimatorEndBuild = ListenerAnimatorEndBuild()
    
        override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout,
                                         child: FloatingActionButton,
                                         directTargetChild: View,
                                         target: View, axes: Int, type: Int): Boolean {
            return axes == ViewCompat.SCROLL_AXIS_VERTICAL
        }
    
    
        override fun onNestedScroll(coordinatorLayout: CoordinatorLayout,
                                    child: FloatingActionButton,
                                    target: View,
                                    dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int,
                                    type: Int) {
            if (dyConsumed > 0 && dyUnconsumed == 0) {
                KLog.d("behavior", "上滑中。。。")
            }
            if (dyConsumed == 0 && dyUnconsumed > 0) {
                KLog.d("behavior", "到边界了还在上滑。。。")
            }
            if (dyConsumed < 0 && dyUnconsumed == 0) {
                KLog.d("behavior", "下滑中。。。")
            }
            if (dyConsumed == 0 && dyUnconsumed < 0) {
                KLog.d("behavior", "到边界了,还在下滑。。。")
            }
    
            //页面向上滑动像素数大于0 || 拉到底还在向上拉 && 退出动画是否正在执行 && FAB按钮当前显示中
            if ((dyConsumed > 0 || dyUnconsumed > 0) && listenerAnimatorEndBuild.isFinish&& child.visibility == View.VISIBLE) {
                //隐藏Fab
                scaleHide(child,listenerAnimatorEndBuild)
            } else if ((dyConsumed < 0 || dyUnconsumed < 0) && child.visibility != View.VISIBLE) {
                //显示Fab按钮
                scaleShow(child,null)
            }
        }
        
    }
    
    

    copy过去就能用了 部分动画代码是上网上找的,毕竟我懒的写。。。
    至于是kotlin写的也没关系,之间copy的话 as会自动转为java的。

    相关文章

      网友评论

          本文标题:FloatingActionButton设置Behavior只能

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