summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2015-12-03 07:38:11 -0800
committerChet Haase <chet@google.com>2015-12-08 16:45:23 -0800
commit4610eeff9c6c4789705b6550a57333150d39e970 (patch)
treed777acea26475d105492144f3f7fd80455e3f928 /core/java/android
parentf1b40f65b0a672f17bfebd3c8e93e5f5fb60bdfd (diff)
Revert "Add support for partial view layouts"
This reverts commit c55d5072ac52cee1811b52406419228fa81119ce. There were several bugs related to incorrect handling of various layout issues (layout not being run on containers/views that needed it), reverting to take another run at it outside of master. Issue #25980198 requestLayout() sometimes doesn't result in measure/layout for view Change-Id: Ic0e159cbcf6171652d8fd1bee9ae44a3977cea04
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/view/View.java79
-rw-r--r--core/java/android/view/ViewGroup.java170
-rw-r--r--core/java/android/view/ViewParent.java49
-rw-r--r--core/java/android/view/ViewRootImpl.java79
-rw-r--r--core/java/android/widget/AbsListView.java5
-rw-r--r--core/java/android/widget/FrameLayout.java11
-rw-r--r--core/java/android/widget/LinearLayout.java57
-rw-r--r--core/java/android/widget/ListView.java2
-rw-r--r--core/java/android/widget/TextView.java94
-rw-r--r--core/java/android/widget/Toolbar.java5
10 files changed, 98 insertions, 453 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6dd87a035d23..183ccf3f63a9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -83,7 +83,6 @@ import android.view.AccessibilityIterators.TextSegmentIterator;
import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
import android.view.AccessibilityIterators.WordTextSegmentIterator;
import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
-import android.view.ViewGroup.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
@@ -2423,8 +2422,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* 1 PFLAG3_SCROLL_INDICATOR_END
* 1 PFLAG3_ASSIST_BLOCKED
* 1111111 PFLAG3_POINTER_ICON_MASK
- * 1 PFLAG3_PARTIAL_LAYOUT_REQUESTED
- * 1 PFLAG3_LAYOUT_PARAMS_CHANGED
* |-------|-------|-------|-------|
*/
@@ -2513,7 +2510,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
static final int PFLAG3_SCROLL_INDICATOR_END = 0x2000;
-
/* End of masks for mPrivateFlags3 */
static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
@@ -2652,19 +2648,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private static final int PFLAG3_POINTER_ICON_VALUE_START = 3 << PFLAG3_POINTER_ICON_LSHIFT;
/**
- * Flag indicating that this view has requested a partial layout and
- * is added to the AttachInfo's list of views that need a partial layout
- * request handled on the next traversal.
- */
- static final int PFLAG3_PARTIAL_LAYOUT_REQUESTED = 0x800000;
-
- /**
- * Flag indicating that this view's LayoutParams have been explicitly changed
- * since the last layout pass.
- */
- static final int PFLAG3_LAYOUT_PARAMS_CHANGED = 0x1000000;
-
- /**
* Always allow a user to over-scroll this view, provided it is a
* view that can scroll.
*
@@ -12671,14 +12654,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* ViewGroup.LayoutParams, and these correspond to the different subclasses
* of ViewGroup that are responsible for arranging their children.
*
- * <p>This method may return null if this View is not attached to a parent
+ * This method may return null if this View is not attached to a parent
* ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
* was not invoked successfully. When a View is attached to a parent
- * ViewGroup, this method must not return null.</p>
- *
- * <p>Callers that modify the returned LayoutParams object should call
- * {@link #setLayoutParams(LayoutParams)} to explicitly inform the view that
- * LayoutParams have changed.</p>
+ * ViewGroup, this method must not return null.
*
* @return The LayoutParams associated with this view, or null if no
* parameters have been set yet
@@ -12695,9 +12674,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* correspond to the different subclasses of ViewGroup that are responsible
* for arranging their children.
*
- * <p>If the View's existing LayoutParams object as obtained by {@link #getLayoutParams()} is
- * modified, you should call this method to inform the view that it has changed.</p>
- *
* @param params The layout parameters for this view, cannot be null
*/
public void setLayoutParams(ViewGroup.LayoutParams params) {
@@ -12705,7 +12681,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
throw new NullPointerException("Layout parameters cannot be null");
}
mLayoutParams = params;
- mPrivateFlags3 |= PFLAG3_LAYOUT_PARAMS_CHANGED;
resolveLayoutParams();
if (mParent instanceof ViewGroup) {
((ViewGroup) mParent).onSetLayoutParams(this, params);
@@ -14381,12 +14356,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mParent.requestTransparentRegion(this);
}
- if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
- initialAwakenScrollBars();
- mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
- }
-
- mPrivateFlags3 &= ~(PFLAG3_IS_LAID_OUT | PFLAG3_PARTIAL_LAYOUT_REQUESTED);
+ mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
jumpDrawablesToCurrentState();
@@ -14724,13 +14694,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@CallSuper
protected void onDetachedFromWindowInternal() {
- if (mAttachInfo != null && isPartialLayoutRequested()) {
- mAttachInfo.mPartialLayoutViews.remove(this);
- }
-
mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
- mPrivateFlags3 &= ~(PFLAG3_IS_LAID_OUT | PFLAG3_PARTIAL_LAYOUT_REQUESTED
- | PFLAG3_LAYOUT_PARAMS_CHANGED);
+ mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
removeUnsetPressCallback();
removeLongPressCallback();
@@ -16917,32 +16882,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Indicates whether or not this view has requested a partial layout that
- * may not affect its size or position within its parent. This state will be reset
- * the next time this view is laid out.
- *
- * @return true if partial layout has been requested
- */
- public final boolean isPartialLayoutRequested() {
- return (mPrivateFlags3 & PFLAG3_PARTIAL_LAYOUT_REQUESTED)
- == PFLAG3_PARTIAL_LAYOUT_REQUESTED;
- }
-
- /**
- * Returns true if this view's {@link ViewGroup.LayoutParams LayoutParams} changed
- * since the last time this view was successfully laid out. Typically this happens as a
- * result of a call to {@link #setLayoutParams(LayoutParams)}.
- *
- * @return true if this view's LayoutParams changed since last layout.
- */
- public final boolean didLayoutParamsChange() {
- if (sLayoutParamsAlwaysChanged) {
- return true;
- }
- return (mPrivateFlags3 & PFLAG3_LAYOUT_PARAMS_CHANGED) == PFLAG3_LAYOUT_PARAMS_CHANGED;
- }
-
- /**
* Return true if o is a ViewGroup that is laying out using optical bounds.
* @hide
*/
@@ -16999,7 +16938,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
- mPrivateFlags3 &= ~PFLAG3_LAYOUT_PARAMS_CHANGED;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnLayoutChangeListeners != null) {
@@ -17013,7 +16951,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
- mPrivateFlags3 &= ~PFLAG3_PARTIAL_LAYOUT_REQUESTED;
mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
}
@@ -19111,7 +19048,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags |= PFLAG_INVALIDATED;
if (mParent != null && !mParent.isLayoutRequested()) {
- mParent.requestLayoutForChild(this);
+ mParent.requestLayout();
}
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
mAttachInfo.mViewRequestingLayout = null;
@@ -19130,11 +19067,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags |= PFLAG_INVALIDATED;
}
- void forcePartialLayout() {
- forceLayout();
- mPrivateFlags3 |= PFLAG3_PARTIAL_LAYOUT_REQUESTED;
- }
-
/**
* <p>
* This is called to find out how big a view should be. The parent
@@ -22021,7 +21953,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
interface Callbacks {
void playSoundEffect(int effectId);
boolean performHapticFeedback(int effectId, boolean always);
- void schedulePartialLayout();
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 488063b31ea0..0f7d296a1555 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -60,8 +60,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* <p>
@@ -5531,172 +5529,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
int l, int t, int r, int b);
/**
- * {@inheritDoc}
- *
- * <p>Most subclasses should not need to override this method. The default implementation
- * will call {@link #findDependentLayoutAxes(View, int)} to determine how
- * to optimally proceed. If neither horizontal nor vertical layout depends on the given
- * child, this method will call {@link #requestPartialLayoutForChild(View)}. If one or both
- * do, it will call {@link #requestLayout()}.</p>
- *
- * @param child Child requesting a layout
- */
- @Override
- public void requestLayoutForChild(View child) {
- if (child == null || child.getParent() != this) {
- throw new IllegalArgumentException(
- "child parameter must be a direct child view of this ViewGroup");
- }
-
- // If we don't have a parent ourselves, record that we need a full layout.
- // Our whole subtree is detached.
- final ViewParent parent = getParent();
- if (parent == null) {
- requestLayout();
- return;
- }
-
- // We can optimize the layout request for this child into a partial layout
- // if the child has already been laid out at least once and neither horizontal nor
- // vertical layout within ourselves is dependent on pending layout changes within
- // this child. Otherwise we need to request a full layout for ourselves and continue
- // to recurse up the view hierarchy.
- if (child.isLaidOut() && findDependentLayoutAxes(child, FLAG_LAYOUT_AXIS_ANY) == 0) {
- requestPartialLayoutForChild(child);
- } else {
- requestLayout();
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The default implementation returns {@link #FLAG_LAYOUT_AXIS_ANY}.
- * Optimized implementations for specific ViewGroup subclasses may check if the child's
- * {@link View#didLayoutParamsChange() LayoutParams changed} and in what ways.</p>
- *
- * @param child Direct child of this ViewParent to check
- * @param axisFilter Which axes to check for dependencies. Can be
- * {@link #FLAG_LAYOUT_AXIS_HORIZONTAL}, {@link #FLAG_LAYOUT_AXIS_VERTICAL}
- * or {@link #FLAG_LAYOUT_AXIS_ANY}.
- * @return Axes of this ViewParent that depend on the given child's layout changes
- */
- @Override
- public int findDependentLayoutAxes(View child, int axisFilter) {
- return FLAG_LAYOUT_AXIS_ANY;
- }
-
- /**
- * This is a helper implementation for {@link #findDependentLayoutAxes(View, int)} that
- * is not the default implementation in ViewGroup. This is to preserve compatibility with
- * existing app-side ViewGroup subclasses that existed before the partial layout system was
- * added to Android. It explicitly checks that the LayoutParams of the child are of the
- * expected type so that subclasses of standard framework layouts do not erroneously
- * start believing that it's safe to do a partial layout when that assertion can't
- * reasonably be confirmed.
- *
- * <p>If you're reading this as an author of a custom ViewGroup's findDependentLayoutAxes
- * method you might be frustrated to discover that it is not a part of the Android public API.
- * Many ViewGroup implementations will need to make small but important modifications
- * to an implementation like this one in order to be correct. Instead of encouraging
- * view authors to call this method, then make their own redundant recursive calls to
- * <code>getParent().findDependentLayoutAxes(...)</code> in addition to the one
- * that can happen here, this method is hidden and only used internally.</p>
- *
- * <p>Do feel free to copy this implementation and adapt it to suit your own purposes.</p>
- *
- * @hide
- */
- protected final int findDependentLayoutAxesHelper(View child, int axisFilter,
- Class<?> layoutParamsClass) {
- if (!checkPartialLayoutParams(child, layoutParamsClass)) return axisFilter;
- if (child.didLayoutParamsChange()) {
- // Anything could have changed about our previous assumptions.
- return axisFilter;
- }
-
- final LayoutParams lp = child.getLayoutParams();
-
- // Our layout can always end up depending on a WRAP_CONTENT child.
- final int wrapAxisFilter = ((lp.width == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
- | (lp.height == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
- if (wrapAxisFilter == axisFilter) {
- // We know all queried axes are affected, just return early.
- return wrapAxisFilter;
- }
-
- // Our layout *may* depend on a MATCH_PARENT child, depending on whether we can determine
- // that our layout will remain stable within our parent. We need to ask.
- final int matchAxisFilter = ((lp.width == MATCH_PARENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
- | (lp.height == MATCH_PARENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
- if (matchAxisFilter != 0 || wrapAxisFilter != 0) {
- final ViewParent parent = getParent();
- if (parent != null) {
- // If our parent depends on us for an axis, then our layout can also be affected
- // by a MATCH_PARENT child along that axis.
- return getParent().findDependentLayoutAxes(this, matchAxisFilter)
- | wrapAxisFilter;
- }
-
- // If we don't have a parent, assume we're affected
- // in any determined affected direction.
- return matchAxisFilter | wrapAxisFilter;
- }
-
- // Two exact sizes and LayoutParams didn't change. We're safe.
- return 0;
- }
-
- /**
- * Throw an IllegalArgumentException if the supplied view is not a direct child of
- * this ViewGroup and return false if this view's LayoutParams is not of class lpClass.
- * Implementations of {@link ViewGroup#findDependentLayoutAxes(View, int)} use this
- * to check input parameters and defensively return the full axis filter mask themselves
- * if the LayoutParams class is not of the exact expected type; e.g. it is a subclass
- * of one of the standard framework layouts and we can't make assumptions.
- * @hide
- */
- protected final boolean checkPartialLayoutParams(View child, Class<?> lpClass) {
- if (child.getParent() != this) {
- throw new IllegalArgumentException("View " + child
- + " is not a direct child of " + this);
- }
- final ViewGroup.LayoutParams lp = child.getLayoutParams();
- return lp != null || lp.getClass() == lpClass;
- }
-
- /**
- * Called when a child of this ViewParent requires a relayout before the next frame
- * is drawn, but the caller can guarantee that the size of the child will not change
- * during a measure and layout pass.
- *
- * <p>A call to this method will schedule a partial layout for the supplied view as long as
- * it is a direct child of this ViewGroup and this ViewGroup is attached to a window.
- * On the next scheduled view hierarchy traversal the given child view will be re-measured
- * at its current measured size and re-laid out at its current position within its parent.</p>
- *
- * @param child Child that requires a partial layout
- */
- public void requestPartialLayoutForChild(View child) {
- if (!child.isPartialLayoutRequested()) {
- child.forcePartialLayout();
- if (mAttachInfo != null) {
- final List<View> partialLayoutViews = mAttachInfo.mPartialLayoutViews;
- final boolean schedule = partialLayoutViews.isEmpty();
- partialLayoutViews.add(child);
- if (schedule) {
- mAttachInfo.mRootCallbacks.schedulePartialLayout();
- }
- child.invalidate();
- } else {
- requestLayout();
- }
- }
- }
-
- /**
* Indicates whether the view group has the ability to animate its children
* after the first layout.
*
@@ -6042,7 +5874,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* of its descendants
*/
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
- return new LayoutParams(p);
+ return p;
}
/**
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index f2ab35e90c17..e9b123b5b9be 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -26,11 +26,6 @@ import android.view.accessibility.AccessibilityEvent;
*
*/
public interface ViewParent {
- public static final int FLAG_LAYOUT_AXIS_HORIZONTAL = 1;
- public static final int FLAG_LAYOUT_AXIS_VERTICAL = 2;
- public static final int FLAG_LAYOUT_AXIS_ANY
- = FLAG_LAYOUT_AXIS_HORIZONTAL | FLAG_LAYOUT_AXIS_VERTICAL;
-
/**
* Called when something has changed which has invalidated the layout of a
* child of this view parent. This will schedule a layout pass of the view
@@ -618,48 +613,4 @@ public interface ViewParent {
* @return true if the action was consumed by this ViewParent
*/
public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments);
-
- /**
- * Called when a child of this ViewParent requires a relayout before
- * the next frame is drawn. A call to {@link View#requestLayout() child.requestLayout()}
- * will implicitly result in a call to
- * <code>child.getParent().requestLayoutForChild(child)</code>. App code should not call this
- * method directly. Call <code>child.requestLayout()</code> instead.
- *
- * <p>On versions of Android from API 23 and older, a call to {@link View#requestLayout()}
- * would cause a matching call to <code>requestLayout</code> on each parent view up to
- * the root. With the addition of <code>requestLayoutForChild</code> a view's parent may
- * explicitly decide how to handle a layout request. This allows for optimizations when
- * a view parent knows that a layout-altering change in a child will not affect its own
- * measurement.</p>
- *
- * @param child Child requesting a layout
- */
- public void requestLayoutForChild(View child);
-
- /**
- * Determine which axes of this ViewParent's layout are dependent on the given
- * direct child view. The returned value is a flag set that may contain
- * {@link #FLAG_LAYOUT_AXIS_HORIZONTAL} and/or {@link #FLAG_LAYOUT_AXIS_VERTICAL}.
- * {@link #FLAG_LAYOUT_AXIS_ANY} is provided as a shortcut for
- * <code>FLAG_LAYOUT_AXIS_HORIZONTAL | FLAG_LAYOUT_AXIS_VERTICAL</code>.
- *
- * <p>The given child must be a direct child view. Implementations should throw
- * {@link IllegalArgumentException} otherwise.</p>
- *
- * <p>The caller may specify which axes it cares about. This should be treated as a filter.
- * Implementations should never return a result that would be different from
- * <code>result & axisFilter</code>.</p>
- *
- * @param child Direct child of this ViewParent to check
- * @param axisFilter Which axes to check for dependencies. Can be
- * {@link #FLAG_LAYOUT_AXIS_HORIZONTAL}, {@link #FLAG_LAYOUT_AXIS_VERTICAL}
- * or {@link #FLAG_LAYOUT_AXIS_ANY}.
- * @return Axes of this ViewParent that depend on the given child's layout changes
- *
- * @see #FLAG_LAYOUT_AXIS_HORIZONTAL
- * @see #FLAG_LAYOUT_AXIS_VERTICAL
- * @see #FLAG_LAYOUT_AXIS_ANY
- */
- public int findDependentLayoutAxes(View child, int axisFilter);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b7bb9a3b983f..12cf66ed3b3a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -91,7 +91,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.HashSet;
-import java.util.List;
/**
* The top of a view hierarchy, implementing the needed protocol between View
@@ -953,25 +952,6 @@ public final class ViewRootImpl implements ViewParent,
}
@Override
- public void requestLayoutForChild(View child) {
- requestLayout();
- }
-
- @Override
- public int findDependentLayoutAxes(View child, int axisFilter) {
- if (child != mView) {
- return 0;
- }
-
- final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) child.getLayoutParams();
- final int horizontal = (lp.width == WindowManager.LayoutParams.WRAP_CONTENT
- || lp.horizontalWeight != 0) ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0;
- final int vertical = (lp.height == WindowManager.LayoutParams.WRAP_CONTENT
- || lp.verticalWeight != 0) ? FLAG_LAYOUT_AXIS_VERTICAL : 0;
- return (horizontal | vertical) & axisFilter;
- }
-
- @Override
public boolean isLayoutRequested() {
return mLayoutRequested;
}
@@ -1115,10 +1095,6 @@ public final class ViewRootImpl implements ViewParent,
}
}
- public void schedulePartialLayout() {
- scheduleTraversals();
- }
-
/**
* Notifies the HardwareRenderer that a new frame will be coming soon.
* Currently only {@link ThreadedRenderer} cares about this, and uses
@@ -1958,60 +1934,7 @@ public final class ViewRootImpl implements ViewParent,
|| mAttachInfo.mRecomputeGlobalAttributes;
if (didLayout) {
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
- }
-
- /*
- * Handle partial layouts.
- *
- * Views that have requested partial layouts will not change size or position
- * within their parent view, therefore we will re-measure and re-layout each one
- * after any regularly scheduled layout pass. Any view that already had its
- * isLayoutRequested bit cleared will be skipped, since this means the view has already
- * been measured and laid out on this traversal pass naturally. Views won't be added
- * to this list if layout was already requested when a partial layout is requested
- * for a view, so there should not be duplicates in the list.
- */
- final List<View> partialLayoutViews = mAttachInfo.mPartialLayoutViews;
- final boolean didPartialLayout;
- if (!partialLayoutViews.isEmpty()) {
- // Measurement or layout of views may result in changes to the list
- // of partial-layout views. Swap in an "empty" list to prevent
- // concurrent modification of the list being traversed.
- if (mAttachInfo.mEmptyPartialLayoutViews == null) {
- mAttachInfo.mPartialLayoutViews = new ArrayList<>();
- } else {
- mAttachInfo.mPartialLayoutViews = mAttachInfo.mEmptyPartialLayoutViews;
- }
-
- final int count = partialLayoutViews.size();
- mInLayout = true;
- for (int i = 0; i < count; i++) {
- final View view = partialLayoutViews.get(i);
-
- // Make sure the view is still attached and that it still has layout requested.
- // We might have already serviced the layout request through the standard full-tree
- // layout pass above or even through a previous partial layout view in this list.
- if (view.isAttachedToWindow() && view.isLayoutRequested()) {
- final int widthSpec = MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(),
- MeasureSpec.EXACTLY);
- final int heightSpec = MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(),
- MeasureSpec.EXACTLY);
- view.measure(widthSpec, heightSpec);
- view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
- }
- }
- mInLayout = false;
- didPartialLayout = true;
- triggerGlobalLayoutListener = true;
-
- // The traversal list becomes the new empty list.
- partialLayoutViews.clear();
- mAttachInfo.mEmptyPartialLayoutViews = partialLayoutViews;
- } else {
- didPartialLayout = false;
- }
- if (didLayout || didPartialLayout) {
// By this point all views have been sized and positioned
// We can compute the transparent area
@@ -2041,7 +1964,7 @@ public final class ViewRootImpl implements ViewParent,
if (DBG) {
System.out.println("======================================");
- System.out.println("performTraversals -- after performLayout/partial layout");
+ System.out.println("performTraversals -- after setFrame");
host.debug();
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index f050e49f0b05..e1ce9fe7c039 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2109,11 +2109,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
@Override
- public int findDependentLayoutAxes(View child, int axisFilter) {
- return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mSelector == null) {
useDefaultSelector();
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 4d9f55c2c074..280ff151cd6d 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -21,8 +21,12 @@ import java.util.ArrayList;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
@@ -32,6 +36,9 @@ import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
import android.widget.RemoteViews.RemoteView;
+import com.android.internal.R;
+
+
/**
* FrameLayout is designed to block out an area on the screen to display
* a single item. Generally, FrameLayout should be used to hold a single child view, because it can
@@ -164,10 +171,6 @@ public class FrameLayout extends ViewGroup {
mPaddingBottom + mForegroundPaddingBottom;
}
- @Override
- public int findDependentLayoutAxes(View child, int axisFilter) {
- return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
- }
/**
* {@inheritDoc}
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index bdb1e83438c5..ad939be13a44 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -16,7 +16,6 @@
package android.widget;
-import android.view.ViewParent;
import com.android.internal.R;
import android.annotation.IntDef;
@@ -38,8 +37,6 @@ import android.widget.RemoteViews.RemoteView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* A Layout that arranges its children in a single column or a single row. The direction of
@@ -647,60 +644,6 @@ public class LinearLayout extends ViewGroup {
}
}
- @Override
- public int findDependentLayoutAxes(View child, int axisFilter) {
- // This implementation is almost exactly equivalent to the default implementation
- // offered to the rest of the framework in ViewGroup, but we treat weight to be
- // functionally equivalent to MATCH_PARENT along the orientation axis.
-
- if (!checkPartialLayoutParams(child, LayoutParams.class)) return axisFilter;
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (child.didLayoutParamsChange()) {
- // Anything could have changed about our previous assumptions.
- return axisFilter;
- }
-
- // Our layout can always end up depending on a WRAP_CONTENT child.
- final int wrapAxisFilter = ((lp.width == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
- | (lp.height == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
- if (wrapAxisFilter == axisFilter) {
- // We know all queried axes are affected, just return early.
- return wrapAxisFilter;
- }
-
- // Our layout *may* depend on a MATCH_PARENT child, depending on whether we can determine
- // that our layout will remain stable within our parent. We need to ask.
- int matchAxisFilter = ((lp.width == MATCH_PARENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
- | (lp.height == MATCH_PARENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
- // For LinearLayout, a nonzero weight is equivalent to MATCH_PARENT for this purpose.
- if (lp.weight > 0) {
- if (mOrientation == HORIZONTAL) {
- matchAxisFilter |= FLAG_LAYOUT_AXIS_HORIZONTAL & axisFilter;
- } else {
- matchAxisFilter |= FLAG_LAYOUT_AXIS_VERTICAL & axisFilter;
- }
- }
-
- if (matchAxisFilter != 0 || wrapAxisFilter != 0) {
- final ViewParent parent = getParent();
- if (parent != null) {
- // If our parent depends on us for an axis, then our layout can also be affected
- // by a MATCH_PARENT child along that axis.
- return getParent().findDependentLayoutAxes(this, matchAxisFilter)
- | wrapAxisFilter;
- }
-
- // If we don't have a parent, assume we're affected
- // in any determined affected direction.
- return matchAxisFilter | wrapAxisFilter;
- }
-
- // Two exact sizes and LayoutParams didn't change. We're safe.
- return 0;
- }
-
/**
* Determines where to position dividers between children.
*
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index b43ea76976e1..53ca6d1ba3b1 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1158,7 +1158,7 @@ public class ListView extends AbsListView {
final View child = obtainView(0, mIsScrap);
// Lay out child directly against the parent measure spec so that
- // we can obtain expected minimum width and height.
+ // we can obtain exected minimum width and height.
measureScrapChild(child, 0, widthMeasureSpec, heightSize);
childWidth = child.getMeasuredWidth();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 56513a3d997e..94b75b73bb7d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6814,11 +6814,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mEllipsize == TextUtils.TruncateAt.MARQUEE) {
if (!compressText(ellipsisWidth)) {
+ final int height = mLayoutParams.height;
// If the size of the view does not depend on the size of the text, try to
// start the marquee immediately
- final ViewParent parent = getParent();
- if (parent != null && parent.findDependentLayoutAxes(this,
- ViewParent.FLAG_LAYOUT_AXIS_VERTICAL) == 0) {
+ if (height != LayoutParams.WRAP_CONTENT && height != LayoutParams.MATCH_PARENT) {
startMarquee();
} else {
// Defer the start of the marquee until we know our width (see setFrame())
@@ -7217,9 +7216,37 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* new view layout.
*/
private void checkForResize() {
- // Always request a layout. The parent will perform the correct version
- // of the intended optimizations as part of requestLayoutForChild.
- requestLayout();
+ boolean sizeChanged = false;
+
+ if (mLayout != null) {
+ // Check if our width changed
+ if (mLayoutParams.width == LayoutParams.WRAP_CONTENT) {
+ sizeChanged = true;
+ invalidate();
+ }
+
+ // Check if our height changed
+ if (mLayoutParams.height == LayoutParams.WRAP_CONTENT) {
+ int desiredHeight = getDesiredHeight();
+
+ if (desiredHeight != this.getHeight()) {
+ sizeChanged = true;
+ }
+ } else if (mLayoutParams.height == LayoutParams.MATCH_PARENT) {
+ if (mDesiredHeightAtMeasure >= 0) {
+ int desiredHeight = getDesiredHeight();
+
+ if (desiredHeight != mDesiredHeightAtMeasure) {
+ sizeChanged = true;
+ }
+ }
+ }
+ }
+
+ if (sizeChanged) {
+ requestLayout();
+ // caller will have already invalidated
+ }
}
/**
@@ -7227,11 +7254,56 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* or merely a new text layout.
*/
private void checkForRelayout() {
- // Always request a layout. The parent will perform the correct version
- // of the intended optimizations as part of requestLayoutForChild.
- nullLayouts();
- requestLayout();
- invalidate();
+ // If we have a fixed width, we can just swap in a new text layout
+ // if the text height stays the same or if the view height is fixed.
+
+ if ((mLayoutParams.width != LayoutParams.WRAP_CONTENT ||
+ (mMaxWidthMode == mMinWidthMode && mMaxWidth == mMinWidth)) &&
+ (mHint == null || mHintLayout != null) &&
+ (mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight() > 0)) {
+ // Static width, so try making a new text layout.
+
+ int oldht = mLayout.getHeight();
+ int want = mLayout.getWidth();
+ int hintWant = mHintLayout == null ? 0 : mHintLayout.getWidth();
+
+ /*
+ * No need to bring the text into view, since the size is not
+ * changing (unless we do the requestLayout(), in which case it
+ * will happen at measure).
+ */
+ makeNewLayout(want, hintWant, UNKNOWN_BORING, UNKNOWN_BORING,
+ mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(),
+ false);
+
+ if (mEllipsize != TextUtils.TruncateAt.MARQUEE) {
+ // In a fixed-height view, so use our new text layout.
+ if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
+ mLayoutParams.height != LayoutParams.MATCH_PARENT) {
+ invalidate();
+ return;
+ }
+
+ // Dynamic height, but height has stayed the same,
+ // so use our new text layout.
+ if (mLayout.getHeight() == oldht &&
+ (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
+ invalidate();
+ return;
+ }
+ }
+
+ // We lose: the height has changed and we have a dynamic height.
+ // Request a new view layout using our new text layout.
+ requestLayout();
+ invalidate();
+ } else {
+ // Dynamic width, so we have no choice but to request a new
+ // view layout with a new text layout.
+ nullLayouts();
+ requestLayout();
+ invalidate();
+ }
}
@Override
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 6e565138eff9..acbf5eb8d699 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1368,11 +1368,6 @@ public class Toolbar extends ViewGroup {
}
@Override
- public int findDependentLayoutAxes(View child, int axisFilter) {
- return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
int height = 0;