下面列出了android.support.v4.view.ViewCompat#isAttachedToWindow ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@UiThread private static void animateVisibility(@Nullable final View view, final boolean show, int visibility, int duration) {
if (view == null) {
return;
}
if (!ViewCompat.isAttachedToWindow(view)) {
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
animateSafeVisibility(show, view, visibility, duration);
return true;
}
});
} else {
animateSafeVisibility(show, view, visibility, duration);
}
}
private boolean shouldInheritContext(ViewParent parent) {
if (parent == null) {
// The initial parent is null so just return false
return false;
}
final View windowDecor = getWindow().getDecorView();
while (true) {
if (parent == null) {
// Bingo. We've hit a view which has a null parent before being terminated from
// the loop. This is (most probably) because it's the root view in an inflation
// call, therefore we should inherit. This works as the inflated layout is only
// added to the hierarchy at the end of the inflate() call.
return true;
} else if (parent == windowDecor || !(parent instanceof View)
|| ViewCompat.isAttachedToWindow((View) parent)) {
// We have either hit the window's decor view, a parent which isn't a View
// (i.e. ViewRootImpl), or an attached view, so we know that the original parent
// is currently added to the view hierarchy. This means that it has not be
// inflated in the current inflate() call and we should not inherit the context.
return false;
}
parent = parent.getParent();
}
}
private void fromNormalToEditing() {
if(mDisplayMode == DisplayMode.TOOLBAR) {
setCurrentState(SearchViewState.EDITING);
openSearchInternal(true);
} else if(mDisplayMode == DisplayMode.MENUITEM) {
setCurrentState(SearchViewState.EDITING);
if(ViewCompat.isAttachedToWindow(this))
revealFromMenuItem();
else {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
revealFromMenuItem();
}
});
}
}
mHomeButton.animateState(mHomeButtonOpenIconState);
}
public void openMenu() {
if (!ViewCompat.isAttachedToWindow(this))
return;
requestFocus();
boolean showMenu = true;
if (menuListener != null) {
newNavigationMenu();
showMenu = menuListener.onPrepareMenu(navigationMenu);
}
if (showMenu) {
addMenuItems();
fab.setSelected(true);
} else {
fab.setSelected(false);
}
}
private void fromNormalToEditing() {
if (mDisplayMode == DisplayMode.SCREEN_TOOLBAR) {
setCurrentState(SearchViewState.EDITING);
openSearchInternal(true);
} else if (mDisplayMode == DisplayMode.APPBAR_MENUITEM) {
setCurrentState(SearchViewState.EDITING);
if (ViewCompat.isAttachedToWindow(this))
revealFromMenuItem();
else {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
revealFromMenuItem();
}
});
}
}
mHomeButton.animateState(mHomeButtonOpenIconState);
}
@UiThread public static void circularReveal(final View mRevealView, final View from, final boolean show) {
if (ViewCompat.isAttachedToWindow(mRevealView)) {
if (show) {
if (mRevealView.isShown()) return;
} else {
if (!mRevealView.isShown()) {
return;
}
}
reveal(mRevealView, show, from);
} else {
mRevealView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
mRevealView.getViewTreeObserver().removeOnPreDrawListener(this);
if (show) {
if (mRevealView.isShown()) return true;
} else {
if (!mRevealView.isShown()) {
return true;
}
}
reveal(mRevealView, show, from);
return true;
}
});
}
}
/**
* Please check if the delegate is NULL before call this method If your view
* has the android:visibility attr in xml, this method in view is called
* before your delegate is created
*/
public void onVisibilityChanged(View changedView, int visibility) {
if (visibility == View.VISIBLE) {
// This compat method is interesting, KK has method
// isAttachedToWindow
// < KK is view.getWindowToken() != null
if (ViewCompat.isAttachedToWindow(mView)) {
// Same as mAttachInfo != null
initialAwakenScrollBars();
}
}
}
public final void setState(final int state) {
if (state == mState) {
return;
}
if (mViewRef == null) {
// The view is not laid out yet; modify mState and let onLayoutChild handle it later
if (state == STATE_COLLAPSED || state == STATE_EXPANDED ||
(mHideable && state == STATE_HIDDEN)) {
mState = state;
}
return;
}
final V child = mViewRef.get();
if (child == null) {
return;
}
// Start the animation; wait until a pending layout if there is one.
ViewParent parent = child.getParent();
if (parent != null && parent.isLayoutRequested() && ViewCompat.isAttachedToWindow(child)) {
child.post(new Runnable() {
@Override
public void run() {
startSettlingAnimation(child, state);
}
});
} else {
startSettlingAnimation(child, state);
}
}
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (mIndeterminate && ViewCompat.isAttachedToWindow(this)) {
if (visibility == GONE || visibility == INVISIBLE) {
stopAnimation();
} else if (ViewCompat.isAttachedToWindow(this)) {
startAnimation();
}
}
}
@Override
public void addEventListener(MapEventListener listener) {
eventListeners.add(listener);
if ((ready || ViewCompat.isAttachedToWindow(view)) && form.canDispatchEvent(null, "MapReady")) {
ready = true;
listener.onReady(this);
}
}
public void hide() {
if (!ViewCompat.isAttachedToWindow(this))
return;
if (isMenuOpen()) {
closeMenu();
}
fab.hide();
}
/**
* Gets the logical display to which the view's window has been attached.
*
* @param view The view.
* @return The logical display, or null if the view is not currently attached to a window.
*/
public static Display getDisplay(@NonNull View view) {
if (Build.VERSION.SDK_INT >= 17) {
return view.getDisplay();
}
return ViewCompat.isAttachedToWindow(view) ?
DisplayManagerCompat.getInstance(view.getContext())
.getDisplay(Display.DEFAULT_DISPLAY) : null;
}
public void hide() {
if (!ViewCompat.isAttachedToWindow(this))
return;
if (isMenuOpen()) {
closeMenu();
}
fab.hide();
}
public void closeMenu() {
if (!ViewCompat.isAttachedToWindow(this))
return;
if (isMenuOpen()) {
fab.setSelected(false);
removeFabMenuItems();
if (menuListener != null) {
menuListener.onMenuClosed();
}
}
}
public void closeMenu() {
if (!ViewCompat.isAttachedToWindow(this))
return;
if (isMenuOpen()) {
fab.setSelected(false);
removeFabMenuItems();
if (menuListener != null) {
menuListener.onMenuClosed();
}
}
}
private void destroy() {
if (mFloatingViewManager != null && mFloatingViewManager.getTargetFloatingView() != null) {
mFloatingViewManager.removeAllViewToWindow();
mFloatingViewManager = null;
}
if (mWindowManager != null && mOverlayWindow != null && ViewCompat.isAttachedToWindow(mOverlayWindow))
mWindowManager.removeView(mOverlayWindow);
}
public void show() {
if (!ViewCompat.isAttachedToWindow(this))
return;
setVisibility(View.VISIBLE);
fab.show();
}
@SuppressLint("InflateParams")
private void createBubbleView(Intent intent) {
DisplayMetrics metrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(metrics);
LayoutInflater inflater = LayoutInflater.from(this);
mBubbleView = inflater.inflate(R.layout.floating_bubble, null, false);
mBubbleView.setAlpha(0f);
mBubbleView.setOnClickListener(v -> {
if (mFloatingViewManager == null)
return;
FloatingView floatingView = mFloatingViewManager.getTargetFloatingView();
WindowManager.LayoutParams lp = (WindowManager.LayoutParams) floatingView.getLayoutParams();
final int x = lp.x;
final int y = lp.y;
if (!isInOverlay()) {
boolean portrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
if (mOverlayWindow != null && (portrait != mOverlayWindow.getHeight() > mOverlayWindow.getWidth()))
mSizeHasChanged = true;
moveBubbleForOverlay(true);
} else {
exitOverlay(true, false, x, y);
}
});
mBubbleView.setOnLongClickListener(view -> true);
final FloatingViewManager.Options options = loadOptions(metrics);
if (!ViewCompat.isAttachedToWindow(mOverlayWindow) && mOverlayWindow.getParent() == null) {
WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mOverlayWindow.getLayoutParams();
layoutParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
layoutParams.dimAmount = 0.65f;
mWindowManager.addView(mOverlayWindow, layoutParams);
}
mFloatingViewManager.addViewToWindow(mBubbleView, options);
if (intent == null || !HIDE_FLOATING_ACTION.equals(intent.getAction())) {
mBubbleHidden = false;
mBubbleView.animate().alpha(1f).setDuration(200).setInterpolator(new AccelerateInterpolator())
.setListener(new AnimatorActionListener(() -> {
if (intent != null && CLICKED_FLOATING_ACTION.equals(intent.getAction()) && !mInOverlay) {
mBubbleView.postDelayed(() -> {
int[] positions = moveBubbleForOverlay(true);
doOverlay(positions);
}, 400L); // FIXME
}
}, AnimatorActionListener.ActionType.END));
sRunning = true;
}
if (this.deployedMarginX == 0)
this.deployedMarginX = (int) (17 * metrics.density);
if (this.deployedMarginY == 0)
this.deployedMarginY = (int) (3 * metrics.density);
}
/**
* @return Whether the tab can currently be interacted with by the user. This requires the
* view owned by the Tab to be visible and in a state where the user can interact with
* it (i.e. not in something like the phone tab switcher).
*/
@CalledByNative
public boolean isUserInteractable() {
return !mIsHidden && ViewCompat.isAttachedToWindow(getView());
}
/**
* 判断view是否显示在屏幕上。 但不能判断被上层视图遮盖的情况。
* 参考:https://juejin.im/entry/5dae45f8f265da5ba46f6106 、 https://www.jianshu.com/p/30b0ae304518
*
* @return true -> yes, false -> no
*/
public static boolean isVisibleToUser(View view) {
if (view == null || view.getVisibility() != View.VISIBLE) {
return false;
}
Rect tempVisibleRect = new Rect();
return ViewCompat.isAttachedToWindow(view) && view.getGlobalVisibleRect(tempVisibleRect);
}