ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android支持BottomSheetBehavior附加锚定状态

2019-05-28 00:15:14  阅读:113  来源: 互联网

标签:android android-support-library android-design-library bottom-sheet


我一直在我的应用程序中使用AndroidSlidingUpPanel库.对于自23.1.1以来的Android设计支持库版本,这会破坏我的布局中的一些内容.由于最新版本引入了BottomSheetBehavior,我正在寻找替换AndroidSlidingUpPanel库并使用BottomSheetBehavior.但是,BottomSheetBehavior只有3个状态,隐藏,折叠和展开(以及2个中间状态拖动和稳定). AndroidSlidingUpPanel还具有锚定状态,这是面板在折叠和展开之间捕捉到的状态.我怎么能使用BottomSheetBehavior并获得这个额外的锚定状态?

例如,谷歌的地图应用就有这种行为.

隐:

折叠:

拖动(折叠和锚定之间):

锚定:

拖动(在锚定和扩展之间):

扩展:

当位置具有锚定状态时,可选图像在地图上向上滑动时会出现一些视差效果.当完全展开时,位置名称将成为操作栏标题.我最终也有兴趣实现类似的东西.

我的第一直觉是锚定状态实际上是扩展状态,在面板上方有空的空间,地图仍然可见,是视图的透明部分.然后,锚定和展开状态之间的拖动只是滚动面板视图本身的内容.

这可以通过以下事实得到验证:在锚定状态下,您可以通过滑动面板上方的可见地图区域继续向上滚动面板.视图的这个不可见部分必须在从折叠状态向上滑动的同时扩展到其区域(如可选图像可见),因为在折叠状态下无法从地图向上滑动面板.我想我可以走这条路,但想知道那里是否有更好的方法.

解决方法:

大新闻
因为有关于同一主题的4或5个问题,但有不同的requeriments,我试图回答所有这些非礼貌的管理员删除/关闭他们让我为每个人创建一张票并更改它们以避免“复制粘贴”我将为您提供指向full answer的链接,您可以在其中找到有关如何获得Google地图等完整行为的所有说明.

回答你的问题

How could I use BottomSheetBehavior and get this additional anchored state?

您可以通过以下步骤修改默认的BottomSheetBehavior添加一个stat:

>创建一个Java类并从CoordinatorLayout.Behavior< V>扩展它.
>将粘贴代码从默认的BottomSheetBehavior文件复制到新文件中.
>使用以下代码修改方法clampViewPositionVertical:

@覆盖
public int clampViewPositionVertical(View child,int top,int dy){
    return constrain(top,mMinOffset,mHideable?mParentHeight:mMaxOffset);
}
int constrain(int amount,int low,int high){
    返还金额<低?低:(量>高?高:量);
}
>添加新状态

public static final int STATE_ANCHOR_POINT = X;
>修改下一个方法:onLayoutChild,onStopNestedScroll,BottomSheetBehavior< V> from(V view)和setState(可选)

我将添加这些修改过的方法和link to the example project

public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
    // First let the parent lay it out
    if (mState != STATE_DRAGGING && mState != STATE_SETTLING) {
        if (ViewCompat.getFitsSystemWindows(parent) &&
                !ViewCompat.getFitsSystemWindows(child)) {
            ViewCompat.setFitsSystemWindows(child, true);
        }
        parent.onLayoutChild(child, layoutDirection);
    }
    // Offset the bottom sheet
    mParentHeight = parent.getHeight();
    mMinOffset = Math.max(0, mParentHeight - child.getHeight());
    mMaxOffset = Math.max(mParentHeight - mPeekHeight, mMinOffset);

    //if (mState == STATE_EXPANDED) {
    //    ViewCompat.offsetTopAndBottom(child, mMinOffset);
    //} else if (mHideable && mState == STATE_HIDDEN...
    if (mState == STATE_ANCHOR_POINT) {
        ViewCompat.offsetTopAndBottom(child, mAnchorPoint);
    } else if (mState == STATE_EXPANDED) {
        ViewCompat.offsetTopAndBottom(child, mMinOffset);
    } else if (mHideable && mState == STATE_HIDDEN) {
        ViewCompat.offsetTopAndBottom(child, mParentHeight);
    } else if (mState == STATE_COLLAPSED) {
        ViewCompat.offsetTopAndBottom(child, mMaxOffset);
    }
    if (mViewDragHelper == null) {
        mViewDragHelper = ViewDragHelper.create(parent, mDragCallback);
    }
    mViewRef = new WeakReference<>(child);
    mNestedScrollingChildRef = new WeakReference<>(findScrollingChild(child));
    return true;
}


public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
    if (child.getTop() == mMinOffset) {
        setStateInternal(STATE_EXPANDED);
        return;
    }
    if (target != mNestedScrollingChildRef.get() || !mNestedScrolled) {
        return;
    }
    int top;
    int targetState;
    if (mLastNestedScrollDy > 0) {
        //top = mMinOffset;
        //targetState = STATE_EXPANDED;
        int currentTop = child.getTop();
        if (currentTop > mAnchorPoint) {
            top = mAnchorPoint;
            targetState = STATE_ANCHOR_POINT;
        }
        else {
            top = mMinOffset;
            targetState = STATE_EXPANDED;
        }
    } else if (mHideable && shouldHide(child, getYVelocity())) {
        top = mParentHeight;
        targetState = STATE_HIDDEN;
    } else if (mLastNestedScrollDy == 0) {
        int currentTop = child.getTop();
        if (Math.abs(currentTop - mMinOffset) < Math.abs(currentTop - mMaxOffset)) {
            top = mMinOffset;
            targetState = STATE_EXPANDED;
        } else {
            top = mMaxOffset;
            targetState = STATE_COLLAPSED;
        }
    } else {
        //top = mMaxOffset;
        //targetState = STATE_COLLAPSED;
        int currentTop = child.getTop();
        if (currentTop > mAnchorPoint) {
            top = mMaxOffset;
            targetState = STATE_COLLAPSED;
        }
        else {
            top = mAnchorPoint;
            targetState = STATE_ANCHOR_POINT;
        }
    }
    if (mViewDragHelper.smoothSlideViewTo(child, child.getLeft(), top)) {
        setStateInternal(STATE_SETTLING);
        ViewCompat.postOnAnimation(child, new SettleRunnable(child, targetState));
    } else {
        setStateInternal(targetState);
    }
    mNestedScrolled = false;
}

public final void setState(@State int state) {
    if (state == mState) {
        return;
    }
    if (mViewRef == null) {
        // The view is not laid out yet; modify mState and let onLayoutChild handle it later
        /**
         * New behavior (added: state == STATE_ANCHOR_POINT ||)
         */
        if (state == STATE_COLLAPSED || state == STATE_EXPANDED ||
                state == STATE_ANCHOR_POINT ||
                (mHideable && state == STATE_HIDDEN)) {
            mState = state;
        }
        return;
    }
    V child = mViewRef.get();
    if (child == null) {
        return;
    }
    int top;
    if (state == STATE_COLLAPSED) {
        top = mMaxOffset;
    } else if (state == STATE_ANCHOR_POINT) {
        top = mAnchorPoint;
    } else if (state == STATE_EXPANDED) {
        top = mMinOffset;
    } else if (mHideable && state == STATE_HIDDEN) {
        top = mParentHeight;
    } else {
        throw new IllegalArgumentException("Illegal state argument: " + state);
    }
    setStateInternal(STATE_SETTLING);
    if (mViewDragHelper.smoothSlideViewTo(child, child.getLeft(), top)) {
        ViewCompat.postOnAnimation(child, new SettleRunnable(child, state));
    }
}


public static <V extends View> BottomSheetBehaviorGoogleMapsLike<V> from(V view) {
    ViewGroup.LayoutParams params = view.getLayoutParams();
    if (!(params instanceof CoordinatorLayout.LayoutParams)) {
        throw new IllegalArgumentException("The view is not a child of CoordinatorLayout");
    }
    CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params)
            .getBehavior();
    if (!(behavior instanceof BottomSheetBehaviorGoogleMapsLike)) {
        throw new IllegalArgumentException(
                "The view is not associated with BottomSheetBehaviorGoogleMapsLike");
    }
    return (BottomSheetBehaviorGoogleMapsLike<V>) behavior;
}

你甚至可以使用behavior.setBottomSheetCallback(new BottomSheetBehaviorGoogleMapsLike.BottomSheetCallback(){….

以下是它的外观:
[]

标签:android,android-support-library,android-design-library,bottom-sheet
来源: https://codeday.me/bug/20190527/1166934.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有