下面列出了android.view.View#addOnAttachStateChangeListener ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Attempts to bind a view to a {@link Coordinator}.
*
* Immediately calls provider to obtain a Coordinator for the view. If a non-null Coordinator is
* returned, that Coordinator is permanently bound to the View.
*/
public static void bind(@NonNull View view, @NonNull CoordinatorProvider provider) {
final Coordinator coordinator = provider.provideCoordinator(view);
if (coordinator == null) {
return;
}
View.OnAttachStateChangeListener binding = new Binding(coordinator, view);
view.addOnAttachStateChangeListener(binding);
// Sometimes we missed the first attach because the child's already been added.
// Sometimes we didn't. The binding keeps track to avoid double attachment of the Coordinator,
// and to guard against attachment to two different views simultaneously.
if (isAttachedToWindow(view)) {
binding.onViewAttachedToWindow(view);
}
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = mInflater.inflate(R.layout.view_city_list_item, parent, false);
}
CityListItemVista vista = (CityListItemVista) view;
City city = getItem(position);
// Initialize or reconfigures a Presenter for CityListItemView
CityListItemPresenter presenter = (CityListItemPresenter) view.getTag();
if (presenter == null) {
presenter = new CityListItemPresenter(mTaskExecutor, city);
presenter.start(vista);
view.setTag(presenter);
view.addOnAttachStateChangeListener(new AdapterViewUnBinder(presenter));
} else {
presenter.setCity(city);
}
return view;
}
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
}
if (oldFocus != null) {
oldFocus.removeOnAttachStateChangeListener(this);
}
Looper.myQueue().removeIdleHandler(this);
newFocus.addOnAttachStateChangeListener(this);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
public ForwardingListener(View src) {
mSrc = src;
src.setLongClickable(true);
src.addOnAttachStateChangeListener(this);
mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop();
mTapTimeout = ViewConfiguration.getTapTimeout();
// Use a medium-press timeout. Halfway between tap and long-press.
mLongPressTimeout = (mTapTimeout + ViewConfiguration.getLongPressTimeout()) / 2;
}
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (Exception unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
@Override
public void onScopeStart(Disposable d) {
disposable = d;
final View view = this.view;
if (view == null)
throw new NullPointerException("view is null");
boolean isAttached = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && view.isAttachedToWindow())
|| view.getWindowToken() != null;
if (!isAttached && !ignoreAttach)
throw new OutsideScopeException("View is not attached!");
view.addOnAttachStateChangeListener(this);
}
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
}
if (oldFocus != null) {
oldFocus.removeOnAttachStateChangeListener(this);
}
Looper.myQueue().removeIdleHandler(this);
newFocus.addOnAttachStateChangeListener(this);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
@Override public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
}
if (oldFocus != null) {
oldFocus.removeOnAttachStateChangeListener(this);
}
Looper.myQueue().removeIdleHandler(this);
newFocus.addOnAttachStateChangeListener(this);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
@Override public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
}
if (oldFocus != null) {
oldFocus.removeOnAttachStateChangeListener(this);
}
Looper.myQueue().removeIdleHandler(this);
newFocus.addOnAttachStateChangeListener(this);
}
/**
* @param view the view whose lifecycle is tracked to determine when to not fire the
* observer.
* @param config the {@link UiConfig} object to subscribe to.
* @param observer the observer to adapt. It's {#onDisplayStyleChanged} will be called when
* the configuration changes, provided that {@code view} is attached to the
* window.
*/
public DisplayStyleObserverAdapter(View view, UiConfig config, DisplayStyleObserver observer) {
mObserver = observer;
// TODO(dgn): getParent() is not a good way to test that, but isAttachedToWindow()
// requires API 19.
mIsViewAttached = view.getParent() != null;
view.addOnAttachStateChangeListener(this);
// This call will also assign the initial value to |mCurrentDisplayStyle|
config.addObserver(this);
}
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
}
if (oldFocus != null) {
oldFocus.removeOnAttachStateChangeListener(this);
}
Looper.myQueue().removeIdleHandler(this);
newFocus.addOnAttachStateChangeListener(this);
}
@Override public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
}
if (oldFocus != null) {
oldFocus.removeOnAttachStateChangeListener(this);
}
Looper.myQueue().removeIdleHandler(this);
newFocus.addOnAttachStateChangeListener(this);
}
@Override
public void show(
final ImageSource imageSource,
final ImageOptions imageOptions,
final @Nullable Object callerContext,
final @Nullable ImageListener imageListener,
final View target) {
VitoImageRequest imageRequest =
mVitoImagePipeline.createImageRequest(target.getResources(), imageSource, imageOptions);
final FrescoDrawable2 frescoDrawable = ensureDrawableSet(target);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// If the view is already attached, we should tell this to controller.
if (target.isAttachedToWindow()) {
onAttach(frescoDrawable, imageRequest);
} else {
// The fetch will be submitted later when / if the View is attached.
frescoDrawable.setImageRequest(imageRequest);
frescoDrawable.setCallerContext(callerContext);
frescoDrawable.setImageListener(imageListener);
}
} else {
// Before Kitkat we don't have a good way to know.
// Normally we expect the view to be already attached, thus we always call `onAttach`.
onAttach(frescoDrawable, imageRequest);
}
// `addOnAttachStateChangeListener` is not idempotent
target.removeOnAttachStateChangeListener(sOnAttachStateChangeListenerCallback);
target.addOnAttachStateChangeListener(sOnAttachStateChangeListenerCallback);
}
public FloatingActionModeHelper(FloatingActionMode mode, View target,
FloatingActionMode.Callback callback, int themeResId) {
mMode = mode;
mTarget = target;
mCallback = callback;
final Context context = target.getContext();
mMenu = new FloatingMenuImpl(target.getContext());
mView = new ViewManager(context, themeResId, mode, mMenu, callback);
final View root = mTarget.getRootView();
root.addOnLayoutChangeListener(this);
root.addOnAttachStateChangeListener(this);
mTarget.addOnAttachStateChangeListener(this);
}
@Override
protected void attachToAnchor(View anchor, int xoff, int yoff, int gravity) {
super.attachToAnchor(anchor, xoff, yoff, gravity);
anchor.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
}
public FragmentViewHolder(View itemView) {
super(itemView);
itemView.addOnAttachStateChangeListener(this);
}
/**
* @param view The view whose requests need preparation. It must be attached to a
* window. This object will retain a weak reference to this view, and will unregister itself
* from AccessibilityManager if the view is detached from a window. It will not re-register
* itself.
* @param requestTypes The types of requests that require preparation. Different types may
* be ORed together.
*
* @throws IllegalStateException if the view is not attached to a window.
*/
public AccessibilityRequestPreparer(View view, @RequestTypes int requestTypes) {
if (!view.isAttachedToWindow()) {
throw new IllegalStateException("View must be attached to a window");
}
mViewRef = new WeakReference<>(view);
mRequestTypes = requestTypes;
view.addOnAttachStateChangeListener(new ViewAttachStateListener());
}