下面列出了android.view.View#getViewTreeObserver ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Add an OnGlobalLayoutListener for the view.
* <p>This is just a convenience method for using {@code ViewTreeObserver.OnGlobalLayoutListener()}.
* This also handles removing listener when onGlobalLayout is called.</p>
*
* @param view The target view to add global layout listener.
* @param runnable Runnable to be executed after the view is laid out.
*/
public static void addOnGlobalLayoutListener(final View view, final Runnable runnable) {
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
runnable.run();
}
});
}
private void registerListener(View anchor) {
// Don't do anything if we haven't managed to patch the super listener.
// And don't bother attaching the listener if the anchor view isn't
// attached. This means we'll only have to deal with the real VTO owned
// by the ViewRoot.
if (mSuperScrollListener != null) {
ViewTreeObserver vto = (anchor.getWindowToken() != null) ? anchor.getViewTreeObserver()
: null;
if (vto != mViewTreeObserver) {
if (mViewTreeObserver != null && mViewTreeObserver.isAlive()) {
mViewTreeObserver.removeOnScrollChangedListener(mSuperScrollListener);
}
if ((mViewTreeObserver = vto) != null) {
vto.addOnScrollChangedListener(mSuperScrollListener);
}
}
}
}
/***
* Utility method for ViewTreeObserver
*
* @param view View object
* @param method Method to be called once View is displayed
*/
public static void triggerMethodOnceViewIsDisplayed(final View view, final Callable<Void> method) {
final ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < 16) {
view.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
} else view.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
try {
method.call();
} catch (Exception e) {
Log.e(TAG, "onGlobalLayout " + e.toString());
}
}
});
}
/**
* <br>调用时机:可见性 或者 布局状态改变的时候 如果view背景换了 那么一定invalited那么布局状态一定改变了
* <br>Register a callback to be invoked when the global layout state or the visibility of views within the view tree changes
*
* @param v
* @param gs 枚举表示 测量后是否移除此监听 目的是:为了防止被多次调用 (用完就移除 除非特殊一直想监听)
*/
public static void measure(final View v, final ListenerState gs, final OnMeasureListener oml) {
ViewTreeObserver vto = v.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
int height = v.getMeasuredHeight();
int width = v.getMeasuredWidth();
if (oml != null) {
oml.measureResult(v, width, height);
}
switch (gs) {
case MEASURE_REMOVE:
v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
break;
case MEASURE_CONTINUE:
break;
default:
break;
}
}
});
}
/** @hide */
protected void attachToAnchor(View anchor, int xoff, int yoff, int gravity) {
detachFromAnchor();
final ViewTreeObserver vto = anchor.getViewTreeObserver();
if (vto != null) {
vto.addOnScrollChangedListener(mOnScrollChangedListener);
}
anchor.addOnAttachStateChangeListener(mOnAnchorDetachedListener);
final View anchorRoot = anchor.getRootView();
anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener);
mAnchor = new WeakReference<>(anchor);
mAnchorRoot = new WeakReference<>(anchorRoot);
mIsAnchorRootAttached = anchorRoot.isAttachedToWindow();
mParentRootView = mAnchorRoot;
mAnchorXoff = xoff;
mAnchorYoff = yoff;
mAnchoredGravity = gravity;
}
/**
* Executes the given {@link Runnable} when the view is laid out
**/
public static void onLaidOut(final View view, final Runnable runnable) {
if (isLaidOut(view)) {
runnable.run();
return;
}
final ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ViewTreeObserver trueObserver;
if (observer.isAlive()) {
trueObserver = observer;
} else {
trueObserver = view.getViewTreeObserver();
}
removeGlobalLayoutObserver(trueObserver, this);
runnable.run();
}
});
}
/**
* 播放动画
*
* @param pager
* @param child
*/
private void startAnimationDelay(final ContainerViewPager pager, final View child) {
final float width = pager.getContainerVO().getW();
child.setTranslationX(width);
final ViewTreeObserver observer = child.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < 16) {
child.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
child.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
EBrowserAnimation.animFromRight(child, width, pager.getContainerVO().getAnimTime(),
pager.getContainerVO().getAnimDelayTime(),
new EBrowserAnimation.AnimatorListener() {
@Override
public void onAnimationEnd() {
}
});
}
});
}
/**
* Executes the given {@link java.lang.Runnable} when the view is laid out
**/
static void onLaidOut(final View view, final Runnable runnable) {
if (isLaidOut(view)) {
runnable.run();
return;
}
final ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ViewTreeObserver trueObserver;
if (observer.isAlive()) {
trueObserver = observer;
} else {
trueObserver = view.getViewTreeObserver();
}
removeOnGlobalLayoutListener(trueObserver, this);
runnable.run();
}
});
}
private static void onNextLayout(final View view, final Runnable runnable) {
final ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ViewTreeObserver trueObserver;
if (observer.isAlive()) {
trueObserver = observer;
} else {
trueObserver = view.getViewTreeObserver();
}
trueObserver.removeOnGlobalLayoutListener(this);
runnable.run();
}
});
}
private static void onNextLayout(final View view, final Runnable runnable) {
final ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ViewTreeObserver trueObserver;
if (observer.isAlive()) {
trueObserver = observer;
} else {
trueObserver = view.getViewTreeObserver();
}
trueObserver.removeOnGlobalLayoutListener(this);
runnable.run();
}
});
}
public static MoveData startAnimation(Context context, final View toView, Bundle transitionBundle, Bundle savedInstanceState, final int duration, final TimeInterpolator interpolator) {
final TransitionData transitionData = new TransitionData(context, transitionBundle);
if (transitionData.imageFilePath != null) {
setImageToView(toView, transitionData.imageFilePath);
}
final MoveData moveData = new MoveData();
moveData.toView = toView;
moveData.duration = duration;
if (savedInstanceState == null) {
ViewTreeObserver observer = toView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
toView.getViewTreeObserver().removeOnPreDrawListener(this);
int[] screenLocation = new int[2];
toView.getLocationOnScreen(screenLocation);
moveData.leftDelta = transitionData.thumbnailLeft - screenLocation[0];
moveData.topDelta = transitionData.thumbnailTop - screenLocation[1];
moveData.widthScale = (float) transitionData.thumbnailWidth / toView.getWidth();
moveData.heightScale = (float) transitionData.thumbnailHeight / toView.getHeight();
runEnterAnimation(moveData, interpolator);
return true;
}
});
}
return moveData;
}
public static MoveData startAnimation(Context context, final View toView, Bundle transitionBundle, Bundle savedInstanceState, final int duration, final TimeInterpolator interpolator) {
final TransitionData transitionData = new TransitionData(context, transitionBundle);
if (transitionData.imageFilePath != null) {
setImageToView(toView, transitionData.imageFilePath);
}
final MoveData moveData = new MoveData();
moveData.toView = toView;
moveData.duration = duration;
if (savedInstanceState == null) {
ViewTreeObserver observer = toView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
toView.getViewTreeObserver().removeOnPreDrawListener(this);
int[] screenLocation = new int[2];
toView.getLocationOnScreen(screenLocation);
moveData.leftDelta = transitionData.thumbnailLeft - screenLocation[0];
moveData.topDelta = transitionData.thumbnailTop - screenLocation[1];
moveData.widthScale = (float) transitionData.thumbnailWidth / toView.getWidth();
moveData.heightScale = (float) transitionData.thumbnailHeight / toView.getHeight();
runEnterAnimation(moveData, interpolator);
return true;
}
});
}
return moveData;
}
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
ArrayList<String> sharedElementNames, boolean isReturning, boolean isCrossTask) {
super(activity.getWindow(), sharedElementNames,
getListener(activity, isReturning && !isCrossTask), isReturning);
mActivity = activity;
mIsCrossTask = isCrossTask;
setResultReceiver(resultReceiver);
prepareEnter();
Bundle resultReceiverBundle = new Bundle();
resultReceiverBundle.putParcelable(KEY_REMOTE_RECEIVER, this);
mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
final View decorView = getDecor();
if (decorView != null) {
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (mIsReadyForTransition) {
if (viewTreeObserver.isAlive()) {
viewTreeObserver.removeOnPreDrawListener(this);
} else {
decorView.getViewTreeObserver().removeOnPreDrawListener(this);
}
}
return false;
}
});
}
}
private void addScrollBottomPadding(final View floatingConfirmLayout, final View scrollView) {
final ViewTreeObserver floatingObserver = floatingConfirmLayout.getViewTreeObserver();
floatingObserver.addOnGlobalLayoutListener(() -> {
final int bottomPadding = floatingConfirmLayout.getHeight();
if (scrollView.getPaddingBottom() != bottomPadding) {
scrollView.setPadding(scrollView.getPaddingLeft(), scrollView.getPaddingTop(),
scrollView.getPaddingRight(), bottomPadding);
}
});
}
@Override
public void onViewDetachedFromWindow(View v) {
if (mTreeObserver != null) {
if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
mTreeObserver.removeGlobalOnLayoutListener(this);
}
((View_HasStateListenerSupport)v).removeOnAttachStateChangeListener(this);
}
public static MoveData startAnimation(final View toView, Bundle transitionBundle, Bundle savedInstanceState, final int duration, final TimeInterpolator interpolator, final Animator.AnimatorListener listener) {
Context context = toView.getContext();
if (context instanceof ContextThemeWrapper) {
context = ((ContextThemeWrapper) context).getBaseContext();
}
final TransitionData transitionData = new TransitionData(context, transitionBundle);
if (transitionData.imageFilePath != null) {
setImageToView(toView, transitionData.imageFilePath);
}
final MoveData moveData = new MoveData();
moveData.toView = toView;
moveData.duration = duration;
if (savedInstanceState == null) {
ViewTreeObserver observer = toView.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
toView.getViewTreeObserver().removeOnPreDrawListener(this);
int[] screenLocation = new int[2];
toView.getLocationOnScreen(screenLocation);
moveData.leftDelta = transitionData.thumbnailLeft - screenLocation[0];
moveData.topDelta = transitionData.thumbnailTop - screenLocation[1];
moveData.widthScale = (float) transitionData.thumbnailWidth / toView.getWidth();
moveData.heightScale = (float) transitionData.thumbnailHeight / toView.getHeight();
runEnterAnimation(moveData, interpolator, listener);
return true;
}
});
}
return moveData;
}
private void addNewBlankNote(int index, boolean animateIn){
final View note = View.inflate(this, R.layout.list_item_note, null);
setNoteIndex(note, index);
final EditText noteText = (EditText) note.findViewById(R.id.noteText);
noteText.addTextChangedListener(new NoteTextWatcher(note));
noteText.setOnFocusChangeListener(new NoteFocusChangeListener(note));
noteContainer.addView(note);
if(animateIn){
final ViewTreeObserver observer = note.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
@Override
public boolean onPreDraw() {
observer.removeOnPreDrawListener(this);
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(note, "alpha", 0, 1);
ObjectAnimator yAnimator = ObjectAnimator.ofFloat(note, "y",
note.getTop() + 20, note.getTop());
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnimator, yAnimator);
set.setDuration(200);
set.start();
scrollView.smoothScrollBy(0, note.getHeight());
return true;
}
});
}
}
public static int getViewHeight(final View view) {
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
return view.getHeight();
}
/**
* Add an OnGlobalLayoutListener for the view.
* This is just a convenience method for using {@code ViewTreeObserver.OnGlobalLayoutListener()}.
* This also handles removing listener when onGlobalLayout is called.
*
* @param view the target view to add global layout listener
* @param runnable runnable to be executed after the view is laid out
*/
public static void addOnGlobalLayoutListener(final View view, final Runnable runnable) {
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
runnable.run();
}
});
}
/**
* Adds a {@link Crouton} to the {@link ViewParent} of it's {@link Activity}.
*
* @param crouton
* The {@link Crouton} that should be added.
*/
private void addCroutonToView(final Crouton crouton) {
// don't add if it is already showing
if (crouton.isShowing()) {
return;
}
final View croutonView = crouton.getView();
if (null == croutonView.getParent()) {
ViewGroup.LayoutParams params = croutonView.getLayoutParams();
if (null == params) {
params = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
// display Crouton in ViewGroup is it has been supplied
if (null != crouton.getViewGroup()) {
// TODO implement add to last position feature (need to align with how this will be requested for activity)
if (crouton.getViewGroup() instanceof FrameLayout) {
crouton.getViewGroup().addView(croutonView, params);
} else {
crouton.getViewGroup().addView(croutonView, 0, params);
}
} else {
Activity activity = crouton.getActivity();
if (null == activity || activity.isFinishing()) {
return;
}
handleTranslucentActionBar((ViewGroup.MarginLayoutParams) params, activity);
activity.addContentView(croutonView, params);
}
crouton.fireEvent("show");
}
croutonView.requestLayout(); // This is needed so the animation can use the measured with/height
ViewTreeObserver observer = croutonView.getViewTreeObserver();
if (null != observer) {
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
@TargetApi(16)
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
croutonView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
croutonView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
croutonView.startAnimation(crouton.getInAnimation());
announceForAccessibilityCompat(crouton.getActivity(), crouton.getText());
if (Configuration.DURATION_INFINITE != crouton.getConfiguration().durationInMilliseconds) {
sendMessageDelayed(crouton, Messages.REMOVE_CROUTON,
crouton.getConfiguration().durationInMilliseconds + crouton.getInAnimation().getDuration());
}
}
});
}
}