Родительское представление
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