Skip to content

Commit 2f1e1e4

Browse files
Gilles DebunneAndroid (Google) Code Review
authored andcommitted
Merge "Handle animations in Views' rectangle clipping methods." into ics-mr1
2 parents 43bc6b0 + cea4513 commit 2f1e1e4

File tree

3 files changed

+98
-38
lines changed

3 files changed

+98
-38
lines changed

core/java/android/view/View.java

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8059,9 +8059,9 @@ public void getFocusedRect(Rect r) {
80598059
/**
80608060
* If some part of this view is not clipped by any of its parents, then
80618061
* return that area in r in global (root) coordinates. To convert r to local
8062-
* coordinates, offset it by -globalOffset (e.g. r.offset(-globalOffset.x,
8063-
* -globalOffset.y)) If the view is completely clipped or translated out,
8064-
* return false.
8062+
* coordinates (without taking possible View rotations into account), offset
8063+
* it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
8064+
* If the view is completely clipped or translated out, return false.
80658065
*
80668066
* @param r If true is returned, r holds the global coordinates of the
80678067
* visible portion of this view.
@@ -12152,35 +12152,48 @@ public void getLocationOnScreen(int[] location) {
1215212152
* @param location an array of two integers in which to hold the coordinates
1215312153
*/
1215412154
public void getLocationInWindow(int[] location) {
12155+
// When the view is not attached to a window, this method does not make sense
12156+
if (mAttachInfo == null) return;
12157+
1215512158
if (location == null || location.length < 2) {
12156-
throw new IllegalArgumentException("location must be an array of "
12157-
+ "two integers");
12159+
throw new IllegalArgumentException("location must be an array of two integers");
1215812160
}
1215912161

12160-
location[0] = mLeft;
12161-
location[1] = mTop;
12162-
if (mTransformationInfo != null) {
12163-
location[0] += (int) (mTransformationInfo.mTranslationX + 0.5f);
12164-
location[1] += (int) (mTransformationInfo.mTranslationY + 0.5f);
12162+
float[] position = mAttachInfo.mTmpTransformLocation;
12163+
position[0] = position[1] = 0.0f;
12164+
12165+
if (!hasIdentityMatrix()) {
12166+
getMatrix().mapPoints(position);
1216512167
}
1216612168

12169+
position[0] += mLeft;
12170+
position[1] += mTop;
12171+
1216712172
ViewParent viewParent = mParent;
1216812173
while (viewParent instanceof View) {
12169-
final View view = (View)viewParent;
12170-
location[0] += view.mLeft - view.mScrollX;
12171-
location[1] += view.mTop - view.mScrollY;
12172-
if (view.mTransformationInfo != null) {
12173-
location[0] += (int) (view.mTransformationInfo.mTranslationX + 0.5f);
12174-
location[1] += (int) (view.mTransformationInfo.mTranslationY + 0.5f);
12174+
final View view = (View) viewParent;
12175+
12176+
position[0] -= view.mScrollX;
12177+
position[1] -= view.mScrollY;
12178+
12179+
if (!view.hasIdentityMatrix()) {
12180+
view.getMatrix().mapPoints(position);
1217512181
}
12182+
12183+
position[0] += view.mLeft;
12184+
position[1] += view.mTop;
12185+
1217612186
viewParent = view.mParent;
1217712187
}
1217812188

1217912189
if (viewParent instanceof ViewRootImpl) {
1218012190
// *cough*
12181-
final ViewRootImpl vr = (ViewRootImpl)viewParent;
12182-
location[1] -= vr.mCurScrollY;
12191+
final ViewRootImpl vr = (ViewRootImpl) viewParent;
12192+
position[1] -= vr.mCurScrollY;
1218312193
}
12194+
12195+
location[0] = (int) (position[0] + 0.5f);
12196+
location[1] = (int) (position[1] + 0.5f);
1218412197
}
1218512198

1218612199
/**

core/java/android/view/ViewGroup.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
8080

8181
private static final boolean DBG = false;
82-
82+
8383
/**
8484
* Views which have been hidden or removed which need to be animated on
8585
* their way out.
@@ -4182,15 +4182,42 @@ public void offsetChildrenTopAndBottom(int offset) {
41824182
* {@inheritDoc}
41834183
*/
41844184
public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
4185+
// The View is not attached to a window, 'visible' does not make sense, return false
4186+
if (mAttachInfo == null) return false;
4187+
4188+
final RectF rect = mAttachInfo.mTmpTransformRect;
4189+
rect.set(r);
4190+
4191+
if (!child.hasIdentityMatrix()) {
4192+
child.getMatrix().mapRect(rect);
4193+
}
4194+
41854195
int dx = child.mLeft - mScrollX;
41864196
int dy = child.mTop - mScrollY;
4197+
4198+
rect.offset(dx, dy);
4199+
41874200
if (offset != null) {
4201+
if (!child.hasIdentityMatrix()) {
4202+
float[] position = mAttachInfo.mTmpTransformLocation;
4203+
position[0] = offset.x;
4204+
position[1] = offset.y;
4205+
child.getMatrix().mapPoints(position);
4206+
offset.x = (int) (position[0] + 0.5f);
4207+
offset.y = (int) (position[1] + 0.5f);
4208+
}
41884209
offset.x += dx;
41894210
offset.y += dy;
41904211
}
4191-
r.offset(dx, dy);
4192-
return r.intersect(0, 0, mRight - mLeft, mBottom - mTop) &&
4193-
(mParent == null || mParent.getChildVisibleRect(this, r, offset));
4212+
4213+
if (rect.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {
4214+
if (mParent == null) return true;
4215+
r.set((int) (rect.left + 0.5f), (int) (rect.top + 0.5f),
4216+
(int) (rect.right + 0.5f), (int) (rect.bottom + 0.5f));
4217+
return mParent.getChildVisibleRect(this, r, offset);
4218+
}
4219+
4220+
return false;
41944221
}
41954222

41964223
/**

core/java/android/view/ViewParent.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,16 @@ public interface ViewParent {
6363
/**
6464
* All or part of a child is dirty and needs to be redrawn.
6565
*
66-
* The location array is an array of two int values which respectively
67-
* define the left and the top position of the dirty child.
66+
* <p>The location array is an array of two int values which respectively
67+
* define the left and the top position of the dirty child.</p>
6868
*
69-
* This method must return the parent of this ViewParent if the specified
69+
* <p>This method must return the parent of this ViewParent if the specified
7070
* rectangle must be invalidated in the parent. If the specified rectangle
7171
* does not require invalidation in the parent or if the parent does not
72-
* exist, this method must return null.
72+
* exist, this method must return null.</p>
7373
*
74-
* When this method returns a non-null value, the location array must
75-
* have been updated with the left and top coordinates of this ViewParent.
74+
* <p>When this method returns a non-null value, the location array must
75+
* have been updated with the left and top coordinates of this ViewParent.</p>
7676
*
7777
* @param location An array of 2 ints containing the left and top
7878
* coordinates of the child to invalidate
@@ -115,6 +115,26 @@ public interface ViewParent {
115115
*/
116116
public void clearChildFocus(View child);
117117

118+
/**
119+
* Compute the visible part of a rectangular region defined in terms of a child view's
120+
* coordinates.
121+
*
122+
* <p>Returns the clipped visible part of the rectangle <code>r</code>, defined in the
123+
* <code>child</code>'s local coordinate system. <code>r</code> is modified by this method to
124+
* contain the result, expressed in the global (root) coordinate system.</p>
125+
*
126+
* <p>The resulting rectangle is always axis aligned. If a rotation is applied to a node in the
127+
* View hierarchy, the result is the axis-aligned bounding box of the visible rectangle.</p>
128+
*
129+
* @param child A child View, whose rectangular visible region we want to compute
130+
* @param r The input rectangle, defined in the child coordinate system. Will be overwritten to
131+
* contain the resulting visible rectangle, expressed in global (root) coordinates
132+
* @param offset The input coordinates of a point, defined in the child coordinate system.
133+
* As with the <code>r</code> parameter, this will be overwritten to contain the global (root)
134+
* coordinates of that point.
135+
* A <code>null</code> value is valid (in case you are not interested in this result)
136+
* @return true if the resulting rectangle is not empty, false otherwise
137+
*/
118138
public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset);
119139

120140
/**
@@ -143,11 +163,11 @@ public interface ViewParent {
143163

144164
/**
145165
* Bring up a context menu for the specified view or its ancestors.
146-
* <p>
147-
* In most cases, a subclass does not need to override this. However, if
166+
*
167+
* <p>In most cases, a subclass does not need to override this. However, if
148168
* the subclass is added directly to the window manager (for example,
149169
* {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
150-
* then it should override this and show the context menu.
170+
* then it should override this and show the context menu.</p>
151171
*
152172
* @param originalView The source view where the context menu was first invoked
153173
* @return true if a context menu was displayed
@@ -164,11 +184,11 @@ public interface ViewParent {
164184

165185
/**
166186
* Start an action mode for the specified view.
167-
* <p>
168-
* In most cases, a subclass does not need to override this. However, if the
187+
*
188+
* <p>In most cases, a subclass does not need to override this. However, if the
169189
* subclass is added directly to the window manager (for example,
170190
* {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
171-
* then it should override this and start the action mode.
191+
* then it should override this and start the action mode.</p>
172192
*
173193
* @param originalView The source view where the action mode was first invoked
174194
* @param callback The callback that will handle lifecycle events for the action mode
@@ -188,10 +208,10 @@ public interface ViewParent {
188208
* Called when a child does not want this parent and its ancestors to
189209
* intercept touch events with
190210
* {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
191-
* <p>
192-
* This parent should pass this call onto its parents. This parent must obey
211+
*
212+
* <p>This parent should pass this call onto its parents. This parent must obey
193213
* this request for the duration of the touch (that is, only clear the flag
194-
* after this parent has received an up or a cancel.
214+
* after this parent has received an up or a cancel.</p>
195215
*
196216
* @param disallowIntercept True if the child does not want the parent to
197217
* intercept touch events.
@@ -234,7 +254,7 @@ public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
234254
* the sending. The parent can optionally add a record for itself before
235255
* dispatching the request to its parent. A parent can also choose not to
236256
* respect the request for sending the event. The accessibility event is sent
237-
* by the topmost view in the view tree.
257+
* by the topmost view in the view tree.</p>
238258
*
239259
* @param child The child which requests sending the event.
240260
* @param event The event to be sent.

0 commit comments

Comments
 (0)