下面列出了javax.annotation.OverridingMethodsMustInvokeSuper#androidx.core.view.WindowInsetsCompat 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public boolean onMeasureChild(@NonNull CoordinatorLayout parent, @NonNull View child,
int parentWidthMeasureSpec, int widthUsed,
int parentHeightMeasureSpec, int heightUsed) {
@SuppressLint("RestrictedApi")
WindowInsetsCompat parentInsets = parent.getLastWindowInsets();
if (parentInsets != null) {
int parentHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec);
parentHeightSize -= parentInsets.getSystemWindowInsetTop()
+ parentInsets.getSystemWindowInsetBottom();
int parentHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec);
parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(parentHeightSize,
parentHeightMode);
}
return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed,
parentHeightMeasureSpec, heightUsed);
}
@Override
public void applyWindowInsets() {
if (getParent() == null || !(getParent() instanceof CoordinatorLayout)) {
return;
}
final int paddingBottom = getPaddingBottom();
final int peekHeight = BottomSheetBehavior.from(this).getPeekHeight();
ViewCompat.setOnApplyWindowInsetsListener(this,
new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(),
paddingBottom + insets.getSystemWindowInsetBottom());
BottomSheetBehavior.from(v).setPeekHeight(
peekHeight + insets.getSystemWindowInsetBottom());
insets.consumeSystemWindowInsets();
return insets;
}
});
}
@Override
public void applyWindowInsets() {
final int paddingTop = getPaddingTop();
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
ViewCompat.setOnApplyWindowInsetsListener(this,
new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
v.setPadding(paddingLeft + insets.getSystemWindowInsetLeft(),
paddingTop + insets.getSystemWindowInsetTop(),
paddingRight + insets.getSystemWindowInsetRight(),
v.getPaddingBottom());
return insets;
}
});
}
WindowInsetsCompat onWindowInsetChanged(@NonNull final WindowInsetsCompat insets) {
WindowInsetsCompat newInsets = null;
if (ViewCompat.getFitsSystemWindows(this)) {
// If we're set to fit system windows, keep the insets
newInsets = insets;
}
// If our insets have changed, keep them and invalidate the scroll ranges...
if (!ObjectsCompat.equals(lastInsets, newInsets)) {
lastInsets = newInsets;
requestLayout();
}
// Consume the insets. This is done so that child views with fitSystemWindows=true do not
// get the default padding functionality from View
return insets.consumeSystemWindowInsets();
}
public OpaqueStatusBarRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(
attrs, R.styleable.OpaqueStatusBarRelativeLayout, defStyleAttr, 0);
mInsetDrawable =
ta.getDrawable(R.styleable.OpaqueStatusBarRelativeLayout_colorPrimaryDark);
ta.recycle();
setWillNotDraw(false);
ViewCompat.setOnApplyWindowInsetsListener(this, (View v, WindowInsetsCompat insets) -> {
mTopInset = insets.getSystemWindowInsetTop();
setPadding(0, mTopInset, 0, 0);
ViewCompat.postInvalidateOnAnimation(this);
return insets.consumeSystemWindowInsets();
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) {
WindowInsetsCompat newInsets = null;
if (ViewCompat.getFitsSystemWindows(this)) {
// If we're set to fit system windows, keep the insets
newInsets = insets;
}
// If our insets have changed, keep them and invalidate the scroll ranges...
if (!objectEquals(mLastInsets, newInsets)) {
mLastInsets = newInsets;
requestLayout();
}
// Consume the insets. This is done so that child views with fitSystemWindows=true do not
// get the default padding functionality from View
return insets.consumeSystemWindowInsets();
}
WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) {
WindowInsetsCompat newInsets = null;
if (ViewCompat.getFitsSystemWindows(this)) {
// If we're set to fit system windows, keep the insets
newInsets = insets;
}
// If our insets have changed, keep them and trigger a layout...
if (!ObjectsCompat.equals(lastInsets, newInsets)) {
lastInsets = newInsets;
updateWillNotDraw();
requestLayout();
}
return insets;
}
WindowInsetsCompat onWindowInsetChanged(@NonNull final WindowInsetsCompat insets) {
WindowInsetsCompat newInsets = null;
if (ViewCompat.getFitsSystemWindows(this)) {
// If we're set to fit system windows, keep the insets
newInsets = insets;
}
// If our insets have changed, keep them and invalidate the scroll ranges...
if (!ObjectsCompat.equals(lastInsets, newInsets)) {
lastInsets = newInsets;
requestLayout();
}
// Consume the insets. This is done so that child views with fitSystemWindows=true do not
// get the default padding functionality from View
return insets.consumeSystemWindowInsets();
}
/**
* Creates and returns a listener, which allows to observe when window insets are applied to the
* root view of the view hierarchy, which is modified by the decorator.
*
* @return The listener, which has been created, as an instance of the type {@link
* OnApplyWindowInsetsListener}
*/
private OnApplyWindowInsetsListener createWindowInsetsListener() {
return new OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(final View v,
final WindowInsetsCompat insets) {
systemWindowInsets = insets.hasSystemWindowInsets() ?
new Rect(insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom()) : null;
adaptLayoutParams();
return insets;
}
};
}
@TargetApi(21)
private boolean applySystemWindowInsets21(WindowInsetsCompat insets) {
boolean consumed = false;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (!child.getFitsSystemWindows()) {
continue;
}
Rect childInsets = new Rect(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom());
computeInsetsWithGravity(child, childInsets);
ViewCompat.dispatchApplyWindowInsets(child, insets.replaceSystemWindowInsets(childInsets));
consumed = true;
}
return consumed;
}
public InsetsPercentRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
ViewCompat.setOnApplyWindowInsetsListener(this, new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
setWindowInsets(insets);
return insets.consumeSystemWindowInsets();
}
});
}
private void setWindowInsets(WindowInsetsCompat insets) {
// Now dispatch them to our children
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
insets = ViewCompat.dispatchApplyWindowInsets(child, insets);
if (insets.isConsumed()) {
break;
}
}
}
@Override
protected void onInsetsChanged(WindowInsetsCompat insets) {
// Normally, NavigationView applies the system inset padding to the first menu item, not to the
// NavigationView itself. This doesn't work if the view has no MenuItems. By overriding the
// inset listener and applying the padding directly to the NavigationView, we can get correct
// padding behavior even when there are no menu items.
setPadding(getPaddingLeft(), insets.getSystemWindowInsetTop(), getPaddingRight(),
getPaddingBottom());
}
private void updateBottomSheetPeekHeight(WindowInsetsCompat insets) {
double width =
getScreenWidth(getActivity())
+ insets.getSystemWindowInsetLeft()
+ insets.getSystemWindowInsetRight();
double height =
getScreenHeight(getActivity())
+ insets.getSystemWindowInsetTop()
+ insets.getSystemWindowInsetBottom();
double mapHeight = width / COLLAPSED_MAP_ASPECT_RATIO;
double peekHeight = height - mapHeight;
bottomSheetBehavior.setPeekHeight((int) peekHeight);
}
private WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
int insetBottom = insets.getSystemWindowInsetBottom();
// TODO: Move extra padding to dimens.xml.
// HACK: Fix padding when keyboard is shown; we limit the padding here to prevent the
// watermark from flying up too high due to the combination of translateY and big inset
// size due to keyboard.
setWatermarkPadding(view, 20, 0, 0, Math.min(insetBottom, 250) + 8);
return insets;
}
/** Adjust UI elements with respect to top/bottom insets. */
@OverridingMethodsMustInvokeSuper
protected void onWindowInsetChanged(WindowInsetsCompat insets) {
findViewById(R.id.status_bar_scrim)
.setLayoutParams(
new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, insets.getSystemWindowInsetTop()));
}
@Override
public void applyWindowInsets() {
ViewCompat.setOnApplyWindowInsetsListener(this,
new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(),
v.getPaddingRight(), v.getPaddingBottom());
return insets;
}
});
}
/**
* Creates a listener, which allows to apply the window insets to the tab switcher's padding.
*
* @return The listener, which has been created, as an instance of the type {@link
* OnApplyWindowInsetsListener}. The listener may not be nullFG
*/
@NonNull
private OnApplyWindowInsetsListener createWindowInsetsListener() {
return new OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(final View v,
final WindowInsetsCompat insets) {
int left = insets.getSystemWindowInsetLeft();
int top = insets.getSystemWindowInsetTop();
int right = insets.getSystemWindowInsetRight();
int bottom = insets.getSystemWindowInsetBottom();
tabSwitcher.setPadding(left, top, right, bottom);
float touchableAreaTop = top;
if (tabSwitcher.getLayout() == Layout.TABLET) {
touchableAreaTop += getResources()
.getDimensionPixelSize(R.dimen.tablet_tab_container_height);
}
RectF touchableArea = new RectF(left, touchableAreaTop,
getDisplayWidth(MainActivity.this) - right, touchableAreaTop +
ThemeUtil.getDimensionPixelSize(MainActivity.this, R.attr.actionBarSize));
tabSwitcher.addDragGesture(
new SwipeGesture.Builder().setTouchableArea(touchableArea).create());
tabSwitcher.addDragGesture(
new PullDownGesture.Builder().setTouchableArea(touchableArea).create());
return insets;
}
};
}
/**
* Apply window insets padding for the supplied view.
*
* @param view The view to set the insets padding.
* @param left {@code true} to apply the left window inset padding.
* @param top {@code true} to apply the top window inset padding.
* @param right {@code true} to apply the right window inset padding.
* @param bottom {@code true} to apply the bottom window inset padding.
* @param consume {@code true} to consume the applied window insets.
*/
public static void applyWindowInsets(@Nullable View view, final boolean left,
final boolean top, final boolean right, final boolean bottom, final boolean consume) {
if (view == null) {
return;
}
final int paddingLeft = view.getPaddingLeft();
final int paddingTop = view.getPaddingTop();
final int paddingRight = view.getPaddingRight();
final int paddingBottom = view.getPaddingBottom();
ViewCompat.setOnApplyWindowInsetsListener(view, new OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
v.setPadding(left ? paddingLeft + insets.getSystemWindowInsetLeft(): paddingLeft,
top ? paddingTop + insets.getSystemWindowInsetTop() : paddingTop,
right ? paddingRight + insets.getSystemWindowInsetRight() : paddingRight,
bottom ? paddingBottom + insets.getSystemWindowInsetBottom() : paddingBottom);
return !consume ? insets :
new WindowInsetsCompat.Builder(insets).setSystemWindowInsets(
Insets.of(left ? 0 : insets.getSystemWindowInsetLeft(),
top ? 0 : insets.getSystemWindowInsetTop(),
right ? 0 : insets.getSystemWindowInsetRight(),
bottom ? 0 : insets.getSystemWindowInsetBottom()))
.build();
}
});
requestApplyWindowInsets(view);
}
@Override
protected WindowInsetsCompat applyWindowInsets(ViewController view, WindowInsetsCompat insets) {
ViewCompat.onApplyWindowInsets(view.getView(), insets.replaceSystemWindowInsets(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
Math.max(insets.getSystemWindowInsetBottom() - getBottomInset(), 0)
));
return insets;
}
protected WindowInsetsCompat applyWindowInsets(ViewController view, WindowInsetsCompat insets) {
return insets.replaceSystemWindowInsets(
insets.getSystemWindowInsetLeft(),
0,
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom()
);
}
@Test
@MediumTest
public void testDrawsAboveNavigationBar() {
// Show a simple Snackbar and wait for it to be shown
final Snackbar snackbar = Snackbar.make(coordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_SHORT);
SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar);
final WindowInsetsCompat colLastInsets = coordinatorLayout.getLastWindowInsets();
assertNotNull(colLastInsets);
// Check that the Snackbar view has padding set to display above the nav bar
final View view = snackbar.getView();
assertNotNull(view);
assertEquals(colLastInsets.getSystemWindowInsetBottom(), view.getPaddingBottom());
}
public void dispatchApplyWindowInsets(@NonNull WindowInsetsCompat insets) {
int top = insets.getSystemWindowInsetTop();
if (paddingTopDefault != top) {
paddingTopDefault = top;
// Apply the padding to the top of the view if it has changed.
updateTopPadding();
}
// Always apply the bottom padding.
menuView.setPadding(0, menuView.getPaddingTop(), 0, insets.getSystemWindowInsetBottom());
ViewCompat.dispatchApplyWindowInsets(headerLayout, insets);
}
public ScrimInsetsFrameLayout(
@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a =
ThemeEnforcement.obtainStyledAttributes(
context,
attrs,
R.styleable.ScrimInsetsFrameLayout,
defStyleAttr,
R.style.Widget_Design_ScrimInsetsFrameLayout);
insetForeground = a.getDrawable(R.styleable.ScrimInsetsFrameLayout_insetForeground);
a.recycle();
setWillNotDraw(true); // No need to draw until the insets are adjusted
ViewCompat.setOnApplyWindowInsetsListener(
this,
new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(
View v, @NonNull WindowInsetsCompat insets) {
if (null == ScrimInsetsFrameLayout.this.insets) {
ScrimInsetsFrameLayout.this.insets = new Rect();
}
ScrimInsetsFrameLayout.this.insets.set(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom());
onInsetsChanged(insets);
setWillNotDraw(!insets.hasSystemWindowInsets() || insetForeground == null);
ViewCompat.postInvalidateOnAnimation(ScrimInsetsFrameLayout.this);
return insets.consumeSystemWindowInsets();
}
});
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPreferences = getSharedPreferences("setting", MODE_PRIVATE);
editor = sharedPreferences.edit();
//Q导航栏沉浸
rootview = findViewById(android.R.id.content);
/*ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), new OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
v.setPadding(0,0,0,insets.getSystemWindowInsetBottom());
return insets;
}
});*/
//状态栏icon黑色
int mode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
if (mode == Configuration.UI_MODE_NIGHT_NO) {
this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
rootview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
ViewCompat.setOnApplyWindowInsetsListener(rootview, new OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
rootview.setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(), 0);
return insets;
}
});
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
//rootView.setFitsSystemWindows(true);
//rootView.setPadding(0,0,0,getNavigationBarHeight());
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
//rootView.setFitsSystemWindows(true);
/*if ((Build.VERSION.SDK_INT<Build.VERSION_CODES.Q)|(getNavigationBarHeight()>dp2px(16))) {
//rootView.setPadding(0,0,0,getNavigationBarHeight());
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
//rootView.setFitsSystemWindows(true);
rootView.setPadding(0,0,0,getNavigationBarHeight());
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}else {
//rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
//rootView.setFitsSystemWindows(true);
}
}else {
rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}*/
//设置为miui主题
//setMiuiTheme(BaseActivity.this,0,mode);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
//全局自定义字体
ViewPump.init(ViewPump.builder()
.addInterceptor(new CalligraphyInterceptor(
new CalligraphyConfig.Builder()
.setDefaultFontPath(sharedPreferences.getString("font_path", null))
.setFontAttrId(R.attr.fontPath)
.build()))
.build());
}
void initSliderPager() {
setWillNotDraw(false);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
setFocusable(true);
final Context context = getContext();
mScroller = new OwnScroller(context, DEFAULT_SCROLL_DURATION, sInterpolator);
final ViewConfiguration configuration = ViewConfiguration.get(context);
final float density = context.getResources().getDisplayMetrics().density;
mTouchSlop = configuration.getScaledPagingTouchSlop();
mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density);
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mLeftEdge = new EdgeEffect(context);
mRightEdge = new EdgeEffect(context);
mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);
mCloseEnough = (int) (CLOSE_ENOUGH * density);
mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density);
ViewCompat.setAccessibilityDelegate(this, new MyAccessibilityDelegate());
if (ViewCompat.getImportantForAccessibility(this)
== ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
ViewCompat.setImportantForAccessibility(this,
ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
ViewCompat.setOnApplyWindowInsetsListener(this,
new androidx.core.view.OnApplyWindowInsetsListener() {
private final Rect mTempRect = new Rect();
@Override
public WindowInsetsCompat onApplyWindowInsets(final View v,
final WindowInsetsCompat originalInsets) {
// First let the SliderPager itself try and consume them...
final WindowInsetsCompat applied =
ViewCompat.onApplyWindowInsets(v, originalInsets);
if (applied.isConsumed()) {
// If the SliderPager consumed all insets, return now
return applied;
}
// Now we'll manually dispatch the insets to our children. Since SliderPager
// children are always full-height, we do not want to use the standard
// ViewGroup dispatchApplyWindowInsets since if child 0 consumes them,
// the rest of the children will not receive any insets. To workaround this
// we manually dispatch the applied insets, not allowing children to
// consume them from each other. We do however keep track of any insets
// which are consumed, returning the union of our children's consumption
final Rect res = mTempRect;
res.left = applied.getSystemWindowInsetLeft();
res.top = applied.getSystemWindowInsetTop();
res.right = applied.getSystemWindowInsetRight();
res.bottom = applied.getSystemWindowInsetBottom();
for (int i = 0, count = getChildCount(); i < count; i++) {
final WindowInsetsCompat childInsets = ViewCompat
.dispatchApplyWindowInsets(getChildAt(i), applied);
// Now keep track of any consumed by tracking each dimension's min
// value
res.left = Math.min(childInsets.getSystemWindowInsetLeft(),
res.left);
res.top = Math.min(childInsets.getSystemWindowInsetTop(),
res.top);
res.right = Math.min(childInsets.getSystemWindowInsetRight(),
res.right);
res.bottom = Math.min(childInsets.getSystemWindowInsetBottom(),
res.bottom);
}
// Now return a new WindowInsets, using the consumed window insets
return applied.replaceSystemWindowInsets(
res.left, res.top, res.right, res.bottom);
}
});
}
@Override
protected void onWindowInsetChanged(WindowInsetsCompat insets) {
super.onWindowInsetChanged(insets);
viewModel.onApplyWindowInsets(insets);
}
private void onApplyWindowInsets(WindowInsetsCompat insets) {
toolbarWrapper.setPadding(0, insets.getSystemWindowInsetTop(), 0, 0);
bottomSheetBottomInsetScrim.setMinimumHeight(insets.getSystemWindowInsetBottom());
updateNavViewInsets(insets);
updateBottomSheetPeekHeight(insets);
}
private void updateNavViewInsets(WindowInsetsCompat insets) {
View headerView = navView.getHeaderView(0);
headerView.setPadding(0, insets.getSystemWindowInsetTop(), 0, 0);
}
private void onApplyWindowInsets(WindowInsetsCompat insets) {
observationListContainer.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
}