【问题标题】:Snackbar getAnchorView() vs. parent viewSnackbar getAnchorView() 与父视图
【发布时间】:2020-06-24 14:07:47
【问题描述】:

我已阅读 Snackbar documentation

但不确定小吃店的 parentTarget(父视图)和 anchoredView 之间的区别。

如有错误请指正:

1) parent view 是小吃店从该视图沿着 hierchy 视图向上查找 suitable parent view

2) 合适的父视图不是anchoredView。

当一个人设置parentView(ctor 要求)和anchoredView 时会发生什么?

小吃店会在哪里营业?

【问题讨论】:

  • 你自己试过了吗?

标签: android material-design android-snackbar snackbar


【解决方案1】:

SnackBar 的父视图将告诉您哪个容器或布局将 应绘制小吃吧。通常,snackbar 会寻找协调员 布局作为您作为参数传递的视图的父级,如果它 找不到一个它会采取活动内容布局 (android.R.id.content) Framelayout 作为父级。

代码取自SnackBar

@Nullable
    private static ViewGroup findSuitableParent(View view) {
        ViewGroup fallback = null;
        do {
            if (view instanceof CoordinatorLayout) {
                // We've found a CoordinatorLayout, use it
                return (ViewGroup) view;
            } else if (view instanceof FrameLayout) {
                if (view.getId() == android.R.id.content) {
                    // If we've hit the decor content view, then we didn't find a CoL in the
                    // hierarchy, so use it.
                    return (ViewGroup) view;
                } else {
                    // It's not the content view but we'll use it as our fallback
                    fallback = (ViewGroup) view;
                }
            }
            if (view != null) {
                // Else, we will loop and crawl up the view hierarchy and try to find a parent
                final ViewParent parent = view.getParent();
                view = parent instanceof View ? (View) parent : null;
            }
        } while (view != null);
        // If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
        return fallback;
    }

BaseTransientBottomBar 的锚点会告诉你在哪个视图之上 将显示小吃吧。

代码取自BaseTransientBottomBar

private int calculateBottomMarginForAnchorView() {
    if (anchorView == null) {
      return 0;
    }

    int[] anchorViewLocation = new int[2];
    anchorView.getLocationOnScreen(anchorViewLocation);
    int anchorViewAbsoluteYTop = anchorViewLocation[1];

    int[] targetParentLocation = new int[2];
    targetParent.getLocationOnScreen(targetParentLocation);
    int targetParentAbsoluteYBottom = targetParentLocation[1] + targetParent.getHeight();

    return targetParentAbsoluteYBottom - anchorViewAbsoluteYTop;
  }

...

/** Sets the view the {@link BaseTransientBottomBar} should be anchored above. */
  @NonNull
  public B setAnchorView(@Nullable View anchorView) {
    this.anchorView = anchorView;
    return (B) this;
  }

  /**
   * Sets the id of the view the {@link BaseTransientBottomBar} should be anchored above.
   *
   * @throws IllegalArgumentException if the anchor view is not found.
   */
  @NonNull
  public B setAnchorView(@IdRes int anchorViewId) {
    this.anchorView = targetParent.findViewById(anchorViewId);
    if (this.anchorView == null) {
      throw new IllegalArgumentException("Unable to find anchor view with id: " + anchorViewId);
    }
    return (B) this;
  }

你可以在这里找到 SnackBar 的源代码Material SnackBar 和 BaseTransientBottomBar 这里BaseTransientBottomBar

【讨论】:

  • 谢谢,你能用一个例子解释一下两者的区别吗? on top of which view snackbar will be shownon which container or layout will the snackbar should be drawn.
猜你喜欢
  • 2015-10-11
  • 1970-01-01
  • 2016-02-16
  • 2017-04-10
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
相关资源
最近更新 更多