【问题标题】:Create ListPopUpWindow as designed by Material in Android在 Android 中创建 Material 设计的 ListPopUpWindow
【发布时间】:2017-06-30 20:30:26
【问题描述】:

我正在尝试在 Android 中创建一个选择菜单,而不是使用 Spinner,但我在布局方面遇到了一些问题。如何使用 ListPopUpWindow 创建如下图所示的内容?

谢谢

【问题讨论】:

  • 将 PopupWindow 与您选择的自定义布局一起使用。在你的情况下 ListView 或 RecyclerView。 showAtLocation 或 showAsDropDown 用于固定 popupWindow 位置。这是一个很酷的例子devexchanges.info/2015/02/…
  • 谢谢,它帮助了我。我会努力实现的。

标签: android material-design


【解决方案1】:

我真的很喜欢这些浮动在选定项目上的菜单,因此我创建了自己的 DropDown 类来实现您的案例。它和@uguboz 写的差不多。

我正在使用带有 RecyclerView 的自定义布局的 PopupWindow。然后我处理 onClick,显示该窗口并使用覆盖的 PopupWindow.update() 来计算正确的窗口位置。

最有趣的部分是这段代码:

public class DropDownMenu extends PopupWindow {

    public boolean show(View anchor) {
        mAnchorView = anchor;

        super.showAtLocation(anchor, Gravity.START | Gravity.TOP, 0, 0);

        update();

        return true;
    }

    public void update() {
        final Resources res = getContentView().getContext().getResources();

        int margin = (int) res.getDimension(R.dimen.carbon_margin);
        int itemHeight = (int) res.getDimension(R.dimen.carbon_listItemHeight);
        int marginHalf = (int) res.getDimension(R.dimen.carbon_paddingHalf);

        ArrayAdapter adapter = getAdapter();

        Rect windowRect = new Rect();
        mAnchorView.getWindowVisibleDisplayFrame(windowRect);
        int hWindow = windowRect.bottom - windowRect.top;
        int wWindow = windowRect.right - windowRect.left;

        int[] location = new int[2];
        mAnchorView.getLocationInWindow(location);

        if (mode == DropDown.Mode.Over) {
            int maxHeightAbove = location[1] - windowRect.top - marginHalf * 2;
            int maxItemsAbove = maxHeightAbove / itemHeight;
            int maxHeightBelow = hWindow - location[1] - marginHalf * 2;
            int maxItemsBelow = maxHeightBelow / itemHeight;

            int itemsBelow = Math.min(adapter.getItemCount() - selectedItem, maxItemsBelow);
            int itemsAbove = Math.min(selectedItem, maxItemsAbove);

            int popupX = location[0] - margin - marginHalf;
            int popupY = location[1] - marginHalf * 2 - itemsAbove * itemHeight - (itemHeight - (mAnchorView.getHeight() - mAnchorView.getPaddingTop() -
                    mAnchorView.getPaddingBottom())) / 2 + mAnchorView.getPaddingTop();
            int popupWidth = mAnchorView.getWidth() + margin * 2 + marginHalf * 2 - mAnchorView.getPaddingLeft() - mAnchorView.getPaddingRight();
            int popupHeight = marginHalf * 4 + Math.max(1, itemsAbove + itemsBelow) * itemHeight;

            popupWidth = Math.min(popupWidth, wWindow - marginHalf * 2);
            popupX = Math.max(popupX, 0);
            popupX = Math.min(popupX, wWindow - popupWidth);

            LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
            manager.scrollToPositionWithOffset(selectedItem - itemsAbove, 0);

            update(popupX, popupY, popupWidth, popupHeight);
        } else {
            // not interesting
        }

        super.update();
    }
}

代码太长,无法在此处粘贴所有详细信息,因此我会为您提供课程链接:DropDownMenu。随心所欲地使用它。我希望你会发现代码很有用。

我已经根据指南为该图像制作了一个样本。它可以在指南 -> 菜单/行为下的示例应用程序中找到

【讨论】:

  • 哇,这是很多代码,顺便说一句,我认为这将非常有用:D。非常感谢
  • 有没有教程教你如何导入和使用你的项目?我在执行 SampleActivity 时遇到了一些问题,例如,在 org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler 类型的对象上找不到实现。请从 Android SDK 管理器安装 Android Support Repository。打开 Android SDK 管理器。此存储库已安装。
  • 没有。该项目应该用作 Maven 依赖项(库)或 apk(示例应用程序)。你的情况有点不同,我没有为你准备好任何东西。我想您的问题可能与 Android Studio 版本有关。最新的代码是使用 AS 3.0 canary 5 和 gradle 4.1 m1 开发的。如果您有更多问题或需要帮助,可以在 Carbon 社区 (plus.google.com/u/0/communities/111973718340428039040) 中提问。如果代码有问题,请随时提出问题 (github.com/ZieIony/Carbon/issues)
猜你喜欢
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 2020-12-14
相关资源
最近更新 更多