19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 20fbf097732137a32930d151f7ba6816a5b870c32aJeff Brownimport android.graphics.Region; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 226e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haaseimport java.util.ArrayList; 230f8ffd83745f718a476564f35a2f7fd4637275bcChet Haaseimport java.util.concurrent.CopyOnWriteArrayList; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A view tree observer is used to register listeners that can be notified of global 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * changes in the view tree. Such global events include, but are not limited to, 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * layout of the whole tree, beginning of the drawing pass, touch mode change.... 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A ViewTreeObserver should never be instantiated by applications as it is provided 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the views hierarchy. Refer to {@link android.view.View#getViewTreeObserver()} 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for more information. 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class ViewTreeObserver { 35c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy // Recursive listeners use CopyOnWriteArrayList 36961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn private CopyOnWriteArrayList<OnWindowFocusChangeListener> mOnWindowFocusListeners; 37961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn private CopyOnWriteArrayList<OnWindowAttachListener> mOnWindowAttachListeners; 380f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners; 390f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners; 40c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 41c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy // Non-recursive listeners use CopyOnWriteArray 42c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy // Any listener invoked from ViewRootImpl.performTraversals() should not be recursive 43c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private CopyOnWriteArray<OnGlobalLayoutListener> mOnGlobalLayoutListeners; 44c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private CopyOnWriteArray<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners; 45c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private CopyOnWriteArray<OnScrollChangedListener> mOnScrollChangedListeners; 46c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private CopyOnWriteArray<OnPreDrawListener> mOnPreDrawListeners; 47c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 48c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy // These listeners cannot be mutated during dispatch 4925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy private ArrayList<OnDrawListener> mOnDrawListeners; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAlive = true; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 54961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Interface definition for a callback to be invoked when the view hierarchy is 55961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * attached to and detached from its window. 56961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 57961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public interface OnWindowAttachListener { 58961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 59961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Callback method to be invoked when the view hierarchy is attached to a window 60961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 61961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void onWindowAttached(); 62961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 63961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 64961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Callback method to be invoked when the view hierarchy is detached from a window 65961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 66961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void onWindowDetached(); 67961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 68961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 69961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 70961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Interface definition for a callback to be invoked when the view hierarchy's window 71961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * focus state changes. 72961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 73961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public interface OnWindowFocusChangeListener { 74961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 75961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Callback method to be invoked when the window focus changes in the view tree. 76961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 77961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @param hasFocus Set to true if the window is gaining focus, false if it is 78961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * losing focus. 79961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 80961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void onWindowFocusChanged(boolean hasFocus); 81961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 82961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 83961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when the focus state within 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the view tree changes. 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnGlobalFocusChangeListener { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback method to be invoked when the focus changes in the view tree. When 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the view tree transitions from touch mode to non-touch mode, oldFocus is null. 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When the view tree transitions from non-touch mode to touch mode, newFocus is 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null. When focus changes in non-touch mode (without transition from or to 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch mode) either oldFocus or newFocus can be null. 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param oldFocus The previously focused view, if any. 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param newFocus The newly focused View, if any. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onGlobalFocusChanged(View oldFocus, View newFocus); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when the global layout state 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or the visibility of views within the view tree changes. 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnGlobalLayoutListener { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback method to be invoked when the global layout state or the visibility of views 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * within the view tree changes 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onGlobalLayout(); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when the view tree is about to be drawn. 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnPreDrawListener { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback method to be invoked when the view tree is about to be drawn. At this point, all 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * views in the tree have been measured and given a frame. Clients can use this to adjust 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * their scroll bounds or even to request a new layout before drawing occurs. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Return true to proceed with the current drawing pass, or false to cancel. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.view.View#onMeasure 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.view.View#onLayout 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.view.View#onDraw 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onPreDraw(); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * Interface definition for a callback to be invoked when the view tree is about to be drawn. 13325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy */ 13425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy public interface OnDrawListener { 13525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy /** 13625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p>Callback method to be invoked when the view tree is about to be drawn. At this point, 13725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * views cannot be modified in any way.</p> 13825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 13925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p>Unlike with {@link OnPreDrawListener}, this method cannot be used to cancel the 14025eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * current drawing pass.</p> 14125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 14225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p>An {@link OnDrawListener} listener <strong>cannot be added or removed</strong> 14325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * from this method.</p> 14425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 14525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @see android.view.View#onMeasure 14625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @see android.view.View#onLayout 14725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @see android.view.View#onDraw 14825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy */ 14925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy public void onDraw(); 15025eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 15125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 15225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy /** 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when the touch mode changes. 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnTouchModeChangeListener { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback method to be invoked when the touch mode changes. 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isInTouchMode True if the view hierarchy is now in touch mode, false otherwise. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onTouchModeChanged(boolean isInTouchMode); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * something in the view tree has been scrolled. 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnScrollChangedListener { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback method to be invoked when something in the view tree 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been scrolled. 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onScrollChanged(); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parameters used with OnComputeInternalInsetsListener. 178935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * 179935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * We are not yet ready to commit to this API and support it, so 180935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * @hide 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static class InternalInsetsInfo { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Offsets from the frame of the window at which the content of 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * windows behind it should be placed. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Rect contentInsets = new Rect(); 188c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 190fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Offsets from the frame of the window at which windows behind it 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are visible. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Rect visibleInsets = new Rect(); 194fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown 195fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown /** 196fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Touchable region defined relative to the origin of the frame of the window. 197fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Only used when {@link #setTouchableInsets(int)} is called with 198fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * the option {@link #TOUCHABLE_INSETS_REGION}. 199fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown */ 200fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown public final Region touchableRegion = new Region(); 201fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Option for {@link #setTouchableInsets(int)}: the entire window frame 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can be touched. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int TOUCHABLE_INSETS_FRAME = 0; 207c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Option for {@link #setTouchableInsets(int)}: the area inside of 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the content insets can be touched. 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int TOUCHABLE_INSETS_CONTENT = 1; 213c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Option for {@link #setTouchableInsets(int)}: the area inside of 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the visible insets can be touched. 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int TOUCHABLE_INSETS_VISIBLE = 2; 219fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown 220fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown /** 221fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Option for {@link #setTouchableInsets(int)}: the area inside of 222fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * the provided touchable region in {@link #touchableRegion} can be touched. 223fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown */ 224fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown public static final int TOUCHABLE_INSETS_REGION = 3; 225fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set which parts of the window can be touched: either 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #TOUCHABLE_INSETS_FRAME}, {@link #TOUCHABLE_INSETS_CONTENT}, 229fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * {@link #TOUCHABLE_INSETS_VISIBLE}, or {@link #TOUCHABLE_INSETS_REGION}. 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchableInsets(int val) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchableInsets = val; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mTouchableInsets; 236c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void reset() { 238fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown contentInsets.setEmpty(); 239fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown visibleInsets.setEmpty(); 240fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown touchableRegion.setEmpty(); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchableInsets = TOUCHABLE_INSETS_FRAME; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 2442e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown boolean isEmpty() { 2452e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown return contentInsets.isEmpty() 2462e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown && visibleInsets.isEmpty() 2472e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown && touchableRegion.isEmpty() 2482e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown && mTouchableInsets == TOUCHABLE_INSETS_FRAME; 2492e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown } 2502e05ec3235150a93a3459cd260be45f02dadbe84Jeff Brown 25125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy @Override 25225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy public int hashCode() { 25321f4230274f858bf156441374f0bae84e7334d7aRomain Guy int result = contentInsets.hashCode(); 25421f4230274f858bf156441374f0bae84e7334d7aRomain Guy result = 31 * result + visibleInsets.hashCode(); 25521f4230274f858bf156441374f0bae84e7334d7aRomain Guy result = 31 * result + touchableRegion.hashCode(); 25625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy result = 31 * result + mTouchableInsets; 25725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy return result; 25825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 25925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 2601e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy @Override 2611e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy public boolean equals(Object o) { 26225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy if (this == o) return true; 26325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy if (o == null || getClass() != o.getClass()) return false; 26425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 26525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy InternalInsetsInfo other = (InternalInsetsInfo)o; 26625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy return mTouchableInsets == other.mTouchableInsets && 26725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy contentInsets.equals(other.contentInsets) && 26825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy visibleInsets.equals(other.visibleInsets) && 26925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy touchableRegion.equals(other.touchableRegion); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void set(InternalInsetsInfo other) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentInsets.set(other.contentInsets); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project visibleInsets.set(other.visibleInsets); 275fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown touchableRegion.set(other.touchableRegion); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchableInsets = other.mTouchableInsets; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 279c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when layout has 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completed and the client can compute its interior insets. 283935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * 284935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * We are not yet ready to commit to this API and support it, so 285935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * @hide 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnComputeInternalInsetsListener { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback method to be invoked when layout has completed and the 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client can compute its interior insets. 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inoutInfo Should be filled in by the implementation with 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the information about the insets of the window. This is called 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with whatever values the previous OnComputeInternalInsetsListener 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returned, if there are multiple such listeners in the window. 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onComputeInternalInsets(InternalInsetsInfo inoutInfo); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new ViewTreeObserver. This constructor should not be called 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewTreeObserver() { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Merges all the listeners registered on the specified observer with the listeners 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * registered on this object. After this method is invoked, the specified observer 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will return false in {@link #isAlive()} and should not be used anymore. 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The ViewTreeObserver whose listeners must be added to this observer 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void merge(ViewTreeObserver observer) { 314961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (observer.mOnWindowAttachListeners != null) { 315961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (mOnWindowAttachListeners != null) { 316961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowAttachListeners.addAll(observer.mOnWindowAttachListeners); 317961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } else { 318961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowAttachListeners = observer.mOnWindowAttachListeners; 319961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 320961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 321961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 322961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (observer.mOnWindowFocusListeners != null) { 323961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (mOnWindowFocusListeners != null) { 324961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowFocusListeners.addAll(observer.mOnWindowFocusListeners); 325961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } else { 326961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowFocusListeners = observer.mOnWindowFocusListeners; 327961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 328961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 329961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer.mOnGlobalFocusListeners != null) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnGlobalFocusListeners != null) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalFocusListeners.addAll(observer.mOnGlobalFocusListeners); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalFocusListeners = observer.mOnGlobalFocusListeners; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer.mOnGlobalLayoutListeners != null) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnGlobalLayoutListeners != null) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalLayoutListeners.addAll(observer.mOnGlobalLayoutListeners); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalLayoutListeners = observer.mOnGlobalLayoutListeners; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer.mOnPreDrawListeners != null) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnPreDrawListeners != null) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnPreDrawListeners.addAll(observer.mOnPreDrawListeners); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnPreDrawListeners = observer.mOnPreDrawListeners; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer.mOnTouchModeChangeListeners != null) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnTouchModeChangeListeners != null) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnTouchModeChangeListeners.addAll(observer.mOnTouchModeChangeListeners); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnTouchModeChangeListeners = observer.mOnTouchModeChangeListeners; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer.mOnComputeInternalInsetsListeners != null) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnComputeInternalInsetsListeners != null) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnComputeInternalInsetsListeners.addAll(observer.mOnComputeInternalInsetsListeners); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnComputeInternalInsetsListeners = observer.mOnComputeInternalInsetsListeners; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 370757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy if (observer.mOnScrollChangedListeners != null) { 371757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy if (mOnScrollChangedListeners != null) { 372757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy mOnScrollChangedListeners.addAll(observer.mOnScrollChangedListeners); 373757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy } else { 374757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy mOnScrollChangedListeners = observer.mOnScrollChangedListeners; 375757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy } 376757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy } 377757c697f73561ef4cfae9e3da64e9b2894d24147Mark Brophy 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.kill(); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 382961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Register a callback to be invoked when the view hierarchy is attached to a window. 383961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 384961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @param listener The callback to add 385961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 386961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @throws IllegalStateException If {@link #isAlive()} returns false 387961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 388961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void addOnWindowAttachListener(OnWindowAttachListener listener) { 389961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn checkIsAlive(); 390961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 391961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (mOnWindowAttachListeners == null) { 392961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowAttachListeners 393961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn = new CopyOnWriteArrayList<OnWindowAttachListener>(); 394961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 395961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 396961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowAttachListeners.add(listener); 397961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 398961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 399961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 400961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Remove a previously installed window attach callback. 401961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 402961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @param victim The callback to remove 403961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 404961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @throws IllegalStateException If {@link #isAlive()} returns false 405961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 406961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @see #addOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener) 407961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 408961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void removeOnWindowAttachListener(OnWindowAttachListener victim) { 409961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn checkIsAlive(); 410961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (mOnWindowAttachListeners == null) { 411961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn return; 412961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 413961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowAttachListeners.remove(victim); 414961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 415961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 416961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 417961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Register a callback to be invoked when the window focus state within the view tree changes. 418961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 419961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @param listener The callback to add 420961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 421961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @throws IllegalStateException If {@link #isAlive()} returns false 422961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 423961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void addOnWindowFocusChangeListener(OnWindowFocusChangeListener listener) { 424961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn checkIsAlive(); 425961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 426961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (mOnWindowFocusListeners == null) { 427961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowFocusListeners 428961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn = new CopyOnWriteArrayList<OnWindowFocusChangeListener>(); 429961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 430961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 431961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowFocusListeners.add(listener); 432961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 433961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 434961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 435961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Remove a previously installed window focus change callback. 436961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 437961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @param victim The callback to remove 438961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 439961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @throws IllegalStateException If {@link #isAlive()} returns false 440961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * 441961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * @see #addOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener) 442961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 443961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn public void removeOnWindowFocusChangeListener(OnWindowFocusChangeListener victim) { 444961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn checkIsAlive(); 445961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (mOnWindowFocusListeners == null) { 446961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn return; 447961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 448961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn mOnWindowFocusListeners.remove(victim); 449961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 450961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 451961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the focus state within the view tree changes. 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The callback to add 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addOnGlobalFocusChangeListener(OnGlobalFocusChangeListener listener) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnGlobalFocusListeners == null) { 4620f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase mOnGlobalFocusListeners = new CopyOnWriteArrayList<OnGlobalFocusChangeListener>(); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalFocusListeners.add(listener); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a previously installed focus change callback. 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param victim The callback to remove 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #addOnGlobalFocusChangeListener(OnGlobalFocusChangeListener) 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeOnGlobalFocusChangeListener(OnGlobalFocusChangeListener victim) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnGlobalFocusListeners == null) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalFocusListeners.remove(victim); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the global layout state or the visibility of views 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * within the view tree changes 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The callback to add 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addOnGlobalLayoutListener(OnGlobalLayoutListener listener) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnGlobalLayoutListeners == null) { 497c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mOnGlobalLayoutListeners = new CopyOnWriteArray<OnGlobalLayoutListener>(); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalLayoutListeners.add(listener); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a previously installed global layout callback 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param victim The callback to remove 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 5091e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * 5101e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * @deprecated Use #removeOnGlobalLayoutListener instead 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #addOnGlobalLayoutListener(OnGlobalLayoutListener) 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5141e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy @Deprecated 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGlobalOnLayoutListener(OnGlobalLayoutListener victim) { 5161e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy removeOnGlobalLayoutListener(victim); 5171e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy } 5181e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy 5191e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy /** 5201e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * Remove a previously installed global layout callback 5211e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * 5221e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * @param victim The callback to remove 5231e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * 5241e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * @throws IllegalStateException If {@link #isAlive()} returns false 5251e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * 5261e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy * @see #addOnGlobalLayoutListener(OnGlobalLayoutListener) 5271e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy */ 5281e878d2ff506e7e96bbdb9d06afea43561445b7aRomain Guy public void removeOnGlobalLayoutListener(OnGlobalLayoutListener victim) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnGlobalLayoutListeners == null) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnGlobalLayoutListeners.remove(victim); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the view tree is about to be drawn 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The callback to add 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addOnPreDrawListener(OnPreDrawListener listener) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnPreDrawListeners == null) { 547c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mOnPreDrawListeners = new CopyOnWriteArray<OnPreDrawListener>(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnPreDrawListeners.add(listener); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a previously installed pre-draw callback 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param victim The callback to remove 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #addOnPreDrawListener(OnPreDrawListener) 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeOnPreDrawListener(OnPreDrawListener victim) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnPreDrawListeners == null) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnPreDrawListeners.remove(victim); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 57125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p>Register a callback to be invoked when the view tree is about to be drawn.</p> 57225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from 57325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p> 57425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 57525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @param listener The callback to add 57625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 57725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @throws IllegalStateException If {@link #isAlive()} returns false 57825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy */ 57925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy public void addOnDrawListener(OnDrawListener listener) { 58025eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy checkIsAlive(); 58125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 58225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy if (mOnDrawListeners == null) { 58325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy mOnDrawListeners = new ArrayList<OnDrawListener>(); 58425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 58525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 58625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy mOnDrawListeners.add(listener); 58725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 58825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 58925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy /** 59025eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p>Remove a previously installed pre-draw callback.</p> 59125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from 59225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p> 59325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 59425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @param victim The callback to remove 59525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 59625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @throws IllegalStateException If {@link #isAlive()} returns false 59725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * 59825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * @see #addOnDrawListener(OnDrawListener) 59925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy */ 60025eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy public void removeOnDrawListener(OnDrawListener victim) { 60125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy checkIsAlive(); 60225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy if (mOnDrawListeners == null) { 60325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy return; 60425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 60525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy mOnDrawListeners.remove(victim); 60625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 60725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 60825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy /** 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when a view has been scrolled. 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The callback to add 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addOnScrollChangedListener(OnScrollChangedListener listener) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnScrollChangedListeners == null) { 619c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mOnScrollChangedListeners = new CopyOnWriteArray<OnScrollChangedListener>(); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnScrollChangedListeners.add(listener); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a previously installed scroll-changed callback 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param victim The callback to remove 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #addOnScrollChangedListener(OnScrollChangedListener) 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeOnScrollChangedListener(OnScrollChangedListener victim) { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnScrollChangedListeners == null) { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnScrollChangedListeners.remove(victim); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the invoked when the touch mode changes. 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The callback to add 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addOnTouchModeChangeListener(OnTouchModeChangeListener listener) { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnTouchModeChangeListeners == null) { 6530f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase mOnTouchModeChangeListeners = new CopyOnWriteArrayList<OnTouchModeChangeListener>(); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnTouchModeChangeListeners.add(listener); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a previously installed touch mode change callback 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param victim The callback to remove 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #addOnTouchModeChangeListener(OnTouchModeChangeListener) 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeOnTouchModeChangeListener(OnTouchModeChangeListener victim) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnTouchModeChangeListeners == null) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnTouchModeChangeListeners.remove(victim); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the invoked when it is time to 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * compute the window's internal insets. 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener The callback to add 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 683935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * 684935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * We are not yet ready to commit to this API and support it, so 685935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * @hide 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addOnComputeInternalInsetsListener(OnComputeInternalInsetsListener listener) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnComputeInternalInsetsListeners == null) { 691105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnComputeInternalInsetsListeners = 692c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy new CopyOnWriteArray<OnComputeInternalInsetsListener>(); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnComputeInternalInsetsListeners.add(listener); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a previously installed internal insets computation callback 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param victim The callback to remove 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException If {@link #isAlive()} returns false 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #addOnComputeInternalInsetsListener(OnComputeInternalInsetsListener) 706935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * 707935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * We are not yet ready to commit to this API and support it, so 708935ae463d495d41155e27feb849768ad2b8b16dbDianne Hackborn * @hide 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeOnComputeInternalInsetsListener(OnComputeInternalInsetsListener victim) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkIsAlive(); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnComputeInternalInsetsListeners == null) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnComputeInternalInsetsListeners.remove(victim); 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkIsAlive() { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAlive) { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("This ViewTreeObserver is not alive, call " 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "getViewTreeObserver() again"); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether this ViewTreeObserver is alive. When an observer is not alive, 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * any call to a method (except this one) will throw an exception. 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If an application keeps a long-lived reference to this ViewTreeObserver, it should 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * always check for the result of this method before calling any other method. 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this object is alive and be used, false otherwise. 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAlive() { 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAlive; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Marks this ViewTreeObserver as not alive. After invoking this method, invoking 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * any other method but {@link #isAlive()} and {@link #kill()} will throw an Exception. 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void kill() { 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlive = false; 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 749961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Notifies registered listeners that window has been attached/detached. 750961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 751961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn final void dispatchOnWindowAttachedChange(boolean attached) { 752961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to 753961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // perform the dispatching. The iterator is a safe guard against listeners that 754961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // could mutate the list by calling the various add/remove methods. This prevents 755961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // the array from being modified while we iterate it. 756961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn final CopyOnWriteArrayList<OnWindowAttachListener> listeners 757961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn = mOnWindowAttachListeners; 758961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (listeners != null && listeners.size() > 0) { 759961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn for (OnWindowAttachListener listener : listeners) { 760961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (attached) listener.onWindowAttached(); 761961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn else listener.onWindowDetached(); 762961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 763961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 764961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 765961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 766961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 767961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn * Notifies registered listeners that window focus has changed. 768961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn */ 769961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn final void dispatchOnWindowFocusChange(boolean hasFocus) { 770961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to 771961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // perform the dispatching. The iterator is a safe guard against listeners that 772961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // could mutate the list by calling the various add/remove methods. This prevents 773961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn // the array from being modified while we iterate it. 774961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn final CopyOnWriteArrayList<OnWindowFocusChangeListener> listeners 775961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn = mOnWindowFocusListeners; 776961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn if (listeners != null && listeners.size() > 0) { 777961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn for (OnWindowFocusChangeListener listener : listeners) { 778961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn listener.onWindowFocusChanged(hasFocus); 779961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 780961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 781961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn } 782961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn 783961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn /** 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notifies registered listeners that focus has changed. 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final void dispatchOnGlobalFocusChange(View oldFocus, View newFocus) { 787105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to 788105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // perform the dispatching. The iterator is a safe guard against listeners that 789105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // could mutate the list by calling the various add/remove methods. This prevents 790105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // the array from being modified while we iterate it. 7910f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase final CopyOnWriteArrayList<OnGlobalFocusChangeListener> listeners = mOnGlobalFocusListeners; 7926e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase if (listeners != null && listeners.size() > 0) { 7930f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase for (OnGlobalFocusChangeListener listener : listeners) { 7940f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase listener.onGlobalFocusChanged(oldFocus, newFocus); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notifies registered listeners that a global layout happened. This can be called 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manually if you are forcing a layout on a View or a hierarchy of Views that are 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not attached to a Window or in the GONE state. 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void dispatchOnGlobalLayout() { 805105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to 806105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // perform the dispatching. The iterator is a safe guard against listeners that 807105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // could mutate the list by calling the various add/remove methods. This prevents 808105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // the array from being modified while we iterate it. 809c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy final CopyOnWriteArray<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners; 8106e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase if (listeners != null && listeners.size() > 0) { 811c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy CopyOnWriteArray.Access<OnGlobalLayoutListener> access = listeners.start(); 812c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy try { 813c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy int count = access.size(); 814c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy for (int i = 0; i < count; i++) { 815c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy access.get(i).onGlobalLayout(); 816c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 817c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } finally { 818c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy listeners.end(); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 82421f4230274f858bf156441374f0bae84e7334d7aRomain Guy * Returns whether there are listeners for on pre-draw events. 82521f4230274f858bf156441374f0bae84e7334d7aRomain Guy */ 82621f4230274f858bf156441374f0bae84e7334d7aRomain Guy final boolean hasOnPreDrawListeners() { 82721f4230274f858bf156441374f0bae84e7334d7aRomain Guy return mOnPreDrawListeners != null && mOnPreDrawListeners.size() > 0; 82821f4230274f858bf156441374f0bae84e7334d7aRomain Guy } 82921f4230274f858bf156441374f0bae84e7334d7aRomain Guy 83021f4230274f858bf156441374f0bae84e7334d7aRomain Guy /** 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notifies registered listeners that the drawing pass is about to start. If a 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * listener returns true, then the drawing pass is canceled and rescheduled. This can 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be called manually if you are forcing the drawing on a View or a hierarchy of Views 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that are not attached to a Window or in the GONE state. 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the current draw should be canceled and resceduled, false otherwise. 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 83825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy @SuppressWarnings("unchecked") 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean dispatchOnPreDraw() { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean cancelDraw = false; 841c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy final CopyOnWriteArray<OnPreDrawListener> listeners = mOnPreDrawListeners; 842c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy if (listeners != null && listeners.size() > 0) { 843c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy CopyOnWriteArray.Access<OnPreDrawListener> access = listeners.start(); 844c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy try { 845c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy int count = access.size(); 846c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy for (int i = 0; i < count; i++) { 847c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy cancelDraw |= !(access.get(i).onPreDraw()); 848c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 849c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } finally { 850c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy listeners.end(); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return cancelDraw; 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 85725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy * Notifies registered listeners that the drawing pass is about to start. 85825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy */ 85925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy public final void dispatchOnDraw() { 86025eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy if (mOnDrawListeners != null) { 86125eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy final ArrayList<OnDrawListener> listeners = mOnDrawListeners; 86225eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy int numListeners = listeners.size(); 86325eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy for (int i = 0; i < numListeners; ++i) { 86425eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy listeners.get(i).onDraw(); 86525eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 86625eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 86725eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy } 86825eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy 86925eba5c5029bd91ff7e396b2cca0e4ce024124edRomain Guy /** 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notifies registered listeners that the touch mode has changed. 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inTouchMode True if the touch mode is now enabled, false otherwise. 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final void dispatchOnTouchModeChanged(boolean inTouchMode) { 8750f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase final CopyOnWriteArrayList<OnTouchModeChangeListener> listeners = 876105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnTouchModeChangeListeners; 8776e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase if (listeners != null && listeners.size() > 0) { 8780f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase for (OnTouchModeChangeListener listener : listeners) { 8790f8ffd83745f718a476564f35a2f7fd4637275bcChet Haase listener.onTouchModeChanged(inTouchMode); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notifies registered listeners that something has scrolled. 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final void dispatchOnScrollChanged() { 888105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to 889105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // perform the dispatching. The iterator is a safe guard against listeners that 890105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // could mutate the list by calling the various add/remove methods. This prevents 891105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // the array from being modified while we iterate it. 892c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy final CopyOnWriteArray<OnScrollChangedListener> listeners = mOnScrollChangedListeners; 8936e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase if (listeners != null && listeners.size() > 0) { 894c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy CopyOnWriteArray.Access<OnScrollChangedListener> access = listeners.start(); 895c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy try { 896c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy int count = access.size(); 897c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy for (int i = 0; i < count; i++) { 898c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy access.get(i).onScrollChanged(); 899c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 900c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } finally { 901c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy listeners.end(); 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns whether there are listeners for computing internal insets. 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean hasComputeInternalInsetsListeners() { 910c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy final CopyOnWriteArray<OnComputeInternalInsetsListener> listeners = 911105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnComputeInternalInsetsListeners; 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (listeners != null && listeners.size() > 0); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 914c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Calls all listeners to compute the current insets. 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final void dispatchOnComputeInternalInsets(InternalInsetsInfo inoutInfo) { 919105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to 920105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // perform the dispatching. The iterator is a safe guard against listeners that 921105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // could mutate the list by calling the various add/remove methods. This prevents 922105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // the array from being modified while we iterate it. 923c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy final CopyOnWriteArray<OnComputeInternalInsetsListener> listeners = 924105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnComputeInternalInsetsListeners; 9256e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase if (listeners != null && listeners.size() > 0) { 926c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy CopyOnWriteArray.Access<OnComputeInternalInsetsListener> access = listeners.start(); 927c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy try { 928c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy int count = access.size(); 929c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy for (int i = 0; i < count; i++) { 930c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy access.get(i).onComputeInternalInsets(inoutInfo); 931c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 932c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } finally { 933c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy listeners.end(); 934c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 935c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 936c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 937c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 938c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy /** 939c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * Copy on write array. This array is not thread safe, and only one loop can 940c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * iterate over this array at any given time. This class avoids allocations 941c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * until a concurrent modification happens. 942c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * 943c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * Usage: 944c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * 945c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * CopyOnWriteArray.Access<MyData> access = array.start(); 946c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * try { 947c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * for (int i = 0; i < access.size(); i++) { 948c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * MyData d = access.get(i); 949c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * } 950c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * } finally { 951c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * access.end(); 952c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy * } 953c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy */ 954c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy static class CopyOnWriteArray<T> { 955c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private ArrayList<T> mData = new ArrayList<T>(); 956c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private ArrayList<T> mDataCopy; 957c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 958c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private final Access<T> mAccess = new Access<T>(); 959c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 960c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private boolean mStart; 961c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 962c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy static class Access<T> { 963c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private ArrayList<T> mData; 964c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private int mSize; 965c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 966c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy T get(int index) { 967c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy return mData.get(index); 968c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 969c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 970c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy int size() { 971c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy return mSize; 972c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 973c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 974c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 975c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy CopyOnWriteArray() { 976c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 977c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 978c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy private ArrayList<T> getArray() { 979c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy if (mStart) { 980c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy if (mDataCopy == null) mDataCopy = new ArrayList<T>(mData); 981c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy return mDataCopy; 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 983c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy return mData; 984c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 985c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 986c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy Access<T> start() { 987c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy if (mStart) throw new IllegalStateException("Iteration already started"); 988c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mStart = true; 989c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mDataCopy = null; 990c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mAccess.mData = mData; 991c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mAccess.mSize = mData.size(); 992c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy return mAccess; 993c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 994c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 995c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy void end() { 996c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy if (!mStart) throw new IllegalStateException("Iteration not started"); 997c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mStart = false; 998c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy if (mDataCopy != null) { 999c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mData = mDataCopy; 1000fc343967c8310a425d2df2aefd01fbe60bf3ef3aChet Haase mAccess.mData.clear(); 1001fc343967c8310a425d2df2aefd01fbe60bf3ef3aChet Haase mAccess.mSize = 0; 1002c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 1003c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy mDataCopy = null; 1004c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 1005c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 1006c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy int size() { 1007c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy return getArray().size(); 1008c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 1009c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 1010c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy void add(T item) { 1011c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy getArray().add(item); 1012c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 1013c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 1014c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy void addAll(CopyOnWriteArray<T> array) { 1015c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy getArray().addAll(array.mData); 1016c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 1017c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 1018c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy void remove(T item) { 1019c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy getArray().remove(item); 1020c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy } 1021c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy 1022c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy void clear() { 1023c39ed4a6e54f5b11a2eb07e9aeb58597bd8c78edRomain Guy getArray().clear(); 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1027