【问题标题】:Android "Top Sheet" equivalent of "Bottom Sheet"?Android“顶页”相当于“底页”?
【发布时间】:2021-08-15 05:31:51
【问题描述】:

我想要实现“底部工作表”类型的布局,但“底部”工作表将是一个 MapFragment,它不能很好地用作向上/向下可拖动视图。

我有一个可能很幼稚的想法,将逻辑“翻转”到“Top Sheet”设计,您可以在其中向上/向下拖动 Top Sheet 以显示更多/更少的底部 MapFragment。

ie:从这里...

...到[类似的]这个...

如果有支持设计工具,这是否可能,还是我必须自己推出类似的东西?

【问题讨论】:

  • 我认为您将注册做大量繁重的工作来做两件事。首先,创建您的自定义实现。其次,确定您的实现如何与 android 实现冲突并防范这些情况。我个人认为,Material Design Language 已经到位,可以直观地传达用户期望与应用程序交互的方式。像这样的东西作为个人的学习努力可能很棒,但是一旦你进入市场 - 你需要预料到每个人都不会理解如何使用你的应用程序。
  • 我最终只添加了一个底部布局,其顶部有一个工具栏,允许用户向上拖动工具栏。诀窍是在用户拖动工具栏时调整地图的大小。如果有人感兴趣,我可以发布我的代码。
  • 我想看看@swooby,我正在尝试做类似的事情
  • @odiggity 你可以检查我的答案,我终于让它完全像 BottomSheetBehavior 一样工作,但从顶部开始。

标签: android bottom-sheet


【解决方案1】:

我找到了一个TopSheetBehavior 实现并尝试使其保持最新:https://github.com/carlos-mg89/TopSheetBehavior

事实证明,它在我的情况下效果很好。我发现许多其他 TopSheetBehavior 不完整或已崩溃,但这个不会崩溃并且只需替换行为参数即可开箱即用:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:behavior_hideable="true"
        app:behavior_peekHeight="56dp"
        app:layout_behavior="your.package.components.TopSheetBehavior">

        <!-- Your content goes here -->

    </LinearLayout>

【讨论】:

  • 这是做到这一点的完美方式。它运行良好。
  • 我可以在闭源项目中使用这个精确的解决方案吗?还是我应该提供一些参考资料?
  • @ViktorVostrikov 是的,你可以。它在 Apache 许可下。这里有几个关于 Apache 许可下代码使用的问题得到解答:resources.whitesourcesoftware.com/blog-whitesource/…
  • @CarlosAlbertoMartínezGadea 但是据说我仍然需要以某种方式写图书馆的所有者..不知道我应该提供凭据..
  • 另外,我最近做了一个 RightSheetBehavior github.com/OKatrych/RightSheetBehavior
【解决方案2】:

这是我在上面评论过的解决方案的基础。 稍后我会回来充实它。

@Override
protected void onCreate(
        @Nullable
                Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    if (isFinishing())
    {
        return;
    }


    setContentView(R.layout.activity_home);

    ...

    mGroupBottomSheetFiller = (ViewGroup) findViewById(R.id.groupBottomSheetFiller);

    final NestedScrollView bottomSheetMap = (NestedScrollView) findViewById(R.id.bottomSheetMap);
    mBottomSheetMapBehavior = BottomSheetBehavior.from(bottomSheetMap);
    mBottomSheetMapBehavior.setBottomSheetCallback(new BottomSheetCallback()
    {
        @Override
        public void onStateChanged(
                @NonNull
                        View bottomSheet,
                int newState)
        {
            //Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, newState=" +
            //             bottomSheetBehaviorStateToString(newState) + ')');
            int visibility = isBottomSheetExpanded(mBottomSheetMapBehavior) ? View.VISIBLE : View.GONE;
            mImageBottomSheetMapClose.setVisibility(visibility);
        }

        @Override
        public void onSlide(
                @NonNull
                        View bottomSheet,
                float slideOffset)
        {
            //Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, slideOffset=" + slideOffset + ')');
            resizeMap();
        }
    });
    bottomSheetMap.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
    {
        @Override
        public void onGlobalLayout()
        {
            //Log.e(TAG, "onGlobalLayout()");
            bottomSheetMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            resizeMap();
        }
    });

    ...
}

private void resizeMap()
{
    int screenHeightPixels = PbPlatformUtils.getScreenHeightPixels();
    //Log.e(TAG, "resizeMap: screenHeightPixels=" + screenHeightPixels);

    int[] location = new int[2];
    mGroupMap.getLocationInWindow(location);
    //Log.e(TAG, "resizeMap: getLocationInWindow=" + Arrays.toString(location));

    LayoutParams groupMapLayoutParams = mGroupMap.getLayoutParams();
    groupMapLayoutParams.height = screenHeightPixels - location[1];
    mGroupMap.requestLayout();
}

public static String bottomSheetBehaviorStateToString(int state)
{
    String s;
    switch (state)
    {
        case BottomSheetBehavior.STATE_COLLAPSED:
            s = "STATE_COLLAPSED";
            break;
        case BottomSheetBehavior.STATE_DRAGGING:
            s = "STATE_DRAGGING";
            break;
        case BottomSheetBehavior.STATE_EXPANDED:
            s = "STATE_EXPANDED";
            break;
        case BottomSheetBehavior.STATE_HIDDEN:
            s = "STATE_HIDDEN";
            break;
        case BottomSheetBehavior.STATE_SETTLING:
            s = "STATE_SETTLING";
            break;
        default:
            s = "UNKNOWN";
            break;
    }
    return s + '(' + state + ')';
}

private static boolean isBottomSheetExpanded(
        @NonNull
                BottomSheetBehavior bottomSheetBehavior)
{
    return bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
}

private void bottomSheetMapExpand()
{
    mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
    int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
    mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
    mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapCollapse()
{
    mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
    int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
    mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
    mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
    mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapHide()
{
    mBottomSheetMapBehavior.setHideable(true);
    mBottomSheetMapBehavior.setPeekHeight(0);
    mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
    mGroupBottomSheetFiller.setVisibility(View.GONE);
}

【讨论】:

  • 您是否遇到过此解决方案的兼容性问题?如果您在 Playstore 中有一个使用此功能的工作应用程序,最好检查一下 :)
  • 您可以查看我的答案 @swooby ,也许它更接近您要查找的内容。至少,它的行为与我想象的 TopSheet 等同于 BottomSheetBehavior 完全一样。
  • 看起来不错@CarlosAlbertoMartínezGadea,但我当前答案中的实现符合我对现有生产应用程序的需求,因此我没有尝试移植到您的应用程序。如果有一天我这样做,我会将您的标记为首选答案!谢谢!
  • 您有完整的解决方案吗...我正在做类似的事情,但我找不到有用的材料...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 2017-10-13
  • 2022-12-14
  • 1970-01-01
相关资源
最近更新 更多