| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package android.support.v4.app; |
| |
| |
| import android.view.View; |
| import android.view.ViewTreeObserver; |
| |
| /** |
| * An OnPreDrawListener that will remove itself after one OnPreDraw call. Typical |
| * usage is: |
| * <pre><code> |
| * OneShotPreDrawListener.add(view, () -> { view.doSomething(); }) |
| * </code></pre> |
| * <p> |
| * The onPreDraw always returns true. |
| * <p> |
| * The listener will also remove itself from the ViewTreeObserver when the view |
| * is detached from the view hierarchy. In that case, the Runnable will never be |
| * executed. |
| */ |
| class OneShotPreDrawListener implements ViewTreeObserver.OnPreDrawListener, |
| View.OnAttachStateChangeListener { |
| private final View mView; |
| private ViewTreeObserver mViewTreeObserver; |
| private final Runnable mRunnable; |
| |
| private OneShotPreDrawListener(View view, Runnable runnable) { |
| mView = view; |
| mViewTreeObserver = view.getViewTreeObserver(); |
| mRunnable = runnable; |
| } |
| |
| /** |
| * Creates a OneShotPreDrawListener and adds it to view's ViewTreeObserver. |
| * @param view The view whose ViewTreeObserver the OnPreDrawListener should listen. |
| * @param runnable The Runnable to execute in the OnPreDraw (once) |
| * @return The added OneShotPreDrawListener. It can be removed prior to |
| * the onPreDraw by calling {@link #removeListener()}. |
| */ |
| public static OneShotPreDrawListener add(View view, Runnable runnable) { |
| OneShotPreDrawListener listener = new OneShotPreDrawListener(view, runnable); |
| view.getViewTreeObserver().addOnPreDrawListener(listener); |
| view.addOnAttachStateChangeListener(listener); |
| return listener; |
| } |
| |
| @Override |
| public boolean onPreDraw() { |
| removeListener(); |
| mRunnable.run(); |
| return true; |
| } |
| |
| /** |
| * Removes the listener from the ViewTreeObserver. This is useful to call if the |
| * callback should be removed prior to {@link #onPreDraw()}. |
| */ |
| public void removeListener() { |
| if (mViewTreeObserver.isAlive()) { |
| mViewTreeObserver.removeOnPreDrawListener(this); |
| } else { |
| mView.getViewTreeObserver().removeOnPreDrawListener(this); |
| } |
| mView.removeOnAttachStateChangeListener(this); |
| } |
| |
| @Override |
| public void onViewAttachedToWindow(View v) { |
| mViewTreeObserver = v.getViewTreeObserver(); |
| } |
| |
| @Override |
| public void onViewDetachedFromWindow(View v) { |
| removeListener(); |
| } |
| } |