ViewOverlay.java revision face742d31a7a72a4bdced5594e00e51ecee6c84
191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase/*
291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * Copyright (C) 2013 The Android Open Source Project
391cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase *
491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * Licensed under the Apache License, Version 2.0 (the "License");
591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * you may not use this file except in compliance with the License.
691cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * You may obtain a copy of the License at
791cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase *
891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase *      http://www.apache.org/licenses/LICENSE-2.0
991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase *
1091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * Unless required by applicable law or agreed to in writing, software
1191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * distributed under the License is distributed on an "AS IS" BASIS,
1291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1391cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * See the License for the specific language governing permissions and
1491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase * limitations under the License.
1591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase */
1691cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haasepackage android.view;
1791cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
1891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haaseimport android.content.Context;
1991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haaseimport android.graphics.Canvas;
2091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haaseimport android.graphics.Rect;
2191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haaseimport android.graphics.drawable.Drawable;
2291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
2391cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haaseimport java.util.ArrayList;
2491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
2591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase/**
26edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * An overlay is an extra layer that sits on top of a View (the "host view")
27edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * which is drawn after all other content in that view (including children,
28edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * if the view is a ViewGroup). Interaction with the overlay layer is done
29edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * by adding and removing drawables.
3091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase *
31edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * <p>An overlay requested from a ViewGroup is of type {@link ViewGroupOverlay},
32edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * which also supports adding and removing views.</p>
3391cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase *
34edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * @see View#getOverlay() View.getOverlay()
35edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * @see ViewGroup#getOverlay() ViewGroup.getOverlay()
36edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase * @see ViewGroupOverlay
3791cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase */
38edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haasepublic class ViewOverlay {
3991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
4091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    /**
41edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * The actual container for the drawables (and views, if it's a ViewGroupOverlay).
42edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * All of the management and rendering details for the overlay are handled in
43edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * OverlayViewGroup.
4491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase     */
45edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    OverlayViewGroup mOverlayViewGroup;
46edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
47edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    ViewOverlay(Context context, View hostView) {
48edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        mOverlayViewGroup = new OverlayViewGroup(context, hostView);
49edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    }
5091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
5191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    /**
52edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * Used internally by View and ViewGroup to handle drawing and invalidation
53edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * of the overlay
54edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @return
5591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase     */
56edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    ViewGroup getOverlayView() {
57edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        return mOverlayViewGroup;
5891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    }
5991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
60edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    /**
61edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * Adds a Drawable to the overlay. The bounds of the drawable should be relative to
62edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * the host view. Any drawable added to the overlay should be removed when it is no longer
63edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * needed or no longer visible.
64edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     *
65edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @param drawable The Drawable to be added to the overlay. This drawable will be
66edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * drawn when the view redraws its overlay.
67edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @see #remove(Drawable)
68edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     */
6991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    public void add(Drawable drawable) {
70edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        mOverlayViewGroup.add(drawable);
7191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    }
7291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
73edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    /**
74edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * Removes the specified Drawable from the overlay.
75edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     *
76edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @param drawable The Drawable to be removed from the overlay.
77edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @see #add(Drawable)
78edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     */
7991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    public void remove(Drawable drawable) {
80edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        mOverlayViewGroup.remove(drawable);
8191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    }
8291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
83edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    /**
84edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * Removes all content from the overlay.
85edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     */
86edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    public void clear() {
87edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        mOverlayViewGroup.clear();
88633326e29f008d2b86e523cfeedcbb2a0883181fChet Haase    }
89633326e29f008d2b86e523cfeedcbb2a0883181fChet Haase
90edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    boolean isEmpty() {
91edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        return mOverlayViewGroup.isEmpty();
92edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    }
93edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
94edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    /**
95edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * OverlayViewGroup is a container that View and ViewGroup use to host
96edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * drawables and views added to their overlays  ({@link ViewOverlay} and
97edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * {@link ViewGroupOverlay}, respectively). Drawables are added to the overlay
98edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * via the add/remove methods in ViewOverlay, Views are added/removed via
99edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * ViewGroupOverlay. These drawable and view objects are
100edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * drawn whenever the view itself is drawn; first the view draws its own
101edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * content (and children, if it is a ViewGroup), then it draws its overlay
102edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * (if it has one).
103edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     *
104edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * <p>Besides managing and drawing the list of drawables, this class serves
105edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * two purposes:
106edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * (1) it noops layout calls because children are absolutely positioned and
107edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * (2) it forwards all invalidation calls to its host view. The invalidation
108edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * redirect is necessary because the overlay is not a child of the host view
109edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * and invalidation cannot therefore follow the normal path up through the
110edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * parent hierarchy.</p>
111edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     *
112edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @see View#getOverlay()
113edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @see ViewGroup#getOverlay()
114edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     */
115edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    static class OverlayViewGroup extends ViewGroup {
116edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
117edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        /**
118edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         * The View for which this is an overlay. Invalidations of the overlay are redirected to
119edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         * this host view.
120edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         */
121edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        View mHostView;
122edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
123edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        /**
124edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         * The set of drawables to draw when the overlay is rendered.
125edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         */
126edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        ArrayList<Drawable> mDrawables = null;
127edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
128edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        OverlayViewGroup(Context context, View hostView) {
129edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super(context);
130edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            mHostView = hostView;
131edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            mAttachInfo = mHostView.mAttachInfo;
132edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            mRight = hostView.getWidth();
133edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            mBottom = hostView.getHeight();
134edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
135edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
136edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void add(Drawable drawable) {
137edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mDrawables == null) {
138edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
139edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mDrawables = new ArrayList<Drawable>();
140edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
141edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (!mDrawables.contains(drawable)) {
142edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                // Make each drawable unique in the overlay; can't add it more than once
143edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mDrawables.add(drawable);
144edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                invalidate(drawable.getBounds());
145edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                drawable.setCallback(this);
1469c17fe693deb0cc84099b619185472f192c2b52dChet Haase            }
1479c17fe693deb0cc84099b619185472f192c2b52dChet Haase        }
14891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
149edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void remove(Drawable drawable) {
150edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mDrawables != null) {
151edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mDrawables.remove(drawable);
152edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                invalidate(drawable.getBounds());
153edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                drawable.setCallback(null);
154edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
155edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
15691cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
157edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void add(View child) {
158edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (child.getParent() instanceof ViewGroup) {
159edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                ViewGroup parent = (ViewGroup) child.getParent();
160face742d31a7a72a4bdced5594e00e51ecee6c84Chet Haase                if (parent != mHostView && parent.getParent() != null &&
161face742d31a7a72a4bdced5594e00e51ecee6c84Chet Haase                        parent.mAttachInfo != null) {
162edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    // Moving to different container; figure out how to position child such that
163edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    // it is in the same location on the screen
164edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    int[] parentLocation = new int[2];
165edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    int[] hostViewLocation = new int[2];
166edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    parent.getLocationOnScreen(parentLocation);
167edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    mHostView.getLocationOnScreen(hostViewLocation);
168edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    child.offsetLeftAndRight(parentLocation[0] - hostViewLocation[0]);
169edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
170edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                }
171edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                parent.removeView(child);
172edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
173edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.addView(child);
174edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
17591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
176edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void remove(View view) {
177edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.removeView(view);
17891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
17991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
180edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void clear() {
181edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            removeAllViews();
182edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            mDrawables.clear();
18391cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
18491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
185edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        boolean isEmpty() {
186edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (getChildCount() == 0 &&
187edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    (mDrawables == null || mDrawables.size() == 0)) {
188edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                return true;
189edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
190edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            return false;
191edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
19291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
193edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
194edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void invalidateDrawable(Drawable drawable) {
195edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            invalidate(drawable.getBounds());
196edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
19791cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
198edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
199edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        protected void dispatchDraw(Canvas canvas) {
200edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.dispatchDraw(canvas);
201edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            final int numDrawables = (mDrawables == null) ? 0 : mDrawables.size();
202edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            for (int i = 0; i < numDrawables; ++i) {
203edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mDrawables.get(i).draw(canvas);
204edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
20591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
20691cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
207edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
208edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        protected void onLayout(boolean changed, int l, int t, int r, int b) {
209edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            // Noop: children are positioned absolutely
21091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
21191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
212edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        /*
213edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         The following invalidation overrides exist for the purpose of redirecting invalidation to
214edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         the host view. The overlay is not parented to the host view (since a View cannot be a
215edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         parent), so the invalidation cannot proceed through the normal parent hierarchy.
216edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         There is a built-in assumption that the overlay exactly covers the host view, therefore
217edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         the invalidation rectangles received do not need to be adjusted when forwarded to
218edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         the host view.
219edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase         */
220edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
221edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
222edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void invalidate(Rect dirty) {
223edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidate(dirty);
224edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
225edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidate(dirty);
226edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
22791cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
22891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
229edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
230edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void invalidate(int l, int t, int r, int b) {
231edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidate(l, t, r, b);
232edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
233edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidate(l, t, r, b);
234edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
23591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
23691cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
237edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
238edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void invalidate() {
239edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidate();
240edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
241edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidate();
242edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
24391cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
24491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
245edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
246edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        void invalidate(boolean invalidateCache) {
247edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidate(invalidateCache);
248edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
249edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidate(invalidateCache);
250edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
25191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
25291cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
253edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
254edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
255edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidateViewProperty(invalidateParent, forceRedraw);
256edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
257edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidateViewProperty(invalidateParent, forceRedraw);
258edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
25991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
26091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
261edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
262edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        protected void invalidateParentCaches() {
263edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidateParentCaches();
264edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
265edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidateParentCaches();
266edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
267edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
268edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
269edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
270edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        protected void invalidateParentIfNeeded() {
271edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            super.invalidateParentIfNeeded();
272edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
273edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidateParentIfNeeded();
27491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase            }
27591cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
27691cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase
277edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public void invalidateChildFast(View child, final Rect dirty) {
278edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
279edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                // Note: This is not a "fast" invalidation. Would be nice to instead invalidate
280edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                // using DisplayList properties and a dirty rect instead of causing a real
281edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                // invalidation of the host view
282edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                int left = child.mLeft;
283edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                int top = child.mTop;
284edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                if (!child.getMatrix().isIdentity()) {
285edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    child.transformRect(dirty);
286edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                }
287edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                dirty.offset(left, top);
288edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                mHostView.invalidate(dirty);
2899c17fe693deb0cc84099b619185472f192c2b52dChet Haase            }
29091cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
291edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
292edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        @Override
293edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
294edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            if (mHostView != null) {
295edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                dirty.offset(location[0], location[1]);
296edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                if (mHostView instanceof ViewGroup) {
297edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    location[0] = 0;
298edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    location[1] = 0;
299edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    super.invalidateChildInParent(location, dirty);
300edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    return ((ViewGroup) mHostView).invalidateChildInParent(location, dirty);
301edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                } else {
302edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                    invalidate(dirty);
303edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                }
304edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            }
305edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            return null;
306edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
30791cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase    }
308edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
30991cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase}
310