Merge "more targeted logging"
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index ca1effb..c773527 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -79,7 +79,7 @@
/**
* Map of the children of the {@link AdapterViewAnimator}.
*/
- HashMap<Integer, ViewAndIndex> mViewsMap = new HashMap<Integer, ViewAndIndex>();
+ HashMap<Integer, ViewAndMetaData> mViewsMap = new HashMap<Integer, ViewAndMetaData>();
/**
* List of views pending removal from the {@link AdapterViewAnimator}
@@ -204,13 +204,18 @@
mPreviousViews = new ArrayList<Integer>();
}
- class ViewAndIndex {
- ViewAndIndex(View v, int i) {
- view = v;
- index = i;
- }
+ class ViewAndMetaData {
View view;
- int index;
+ int relativeIndex;
+ int adapterPosition;
+ long itemId;
+
+ ViewAndMetaData(View view, int relativeIndex, int adapterPosition, long itemId) {
+ this.view = view;
+ this.relativeIndex = relativeIndex;
+ this.adapterPosition = adapterPosition;
+ this.itemId = itemId;
+ }
}
/**
@@ -376,6 +381,15 @@
}
}
+ private ViewAndMetaData getMetaDataForChild(View child) {
+ for (ViewAndMetaData vm: mViewsMap.values()) {
+ if (vm.view == child) {
+ return vm;
+ }
+ }
+ return null;
+ }
+
LayoutParams createOrReuseLayoutParams(View v) {
final ViewGroup.LayoutParams currentLp = v.getLayoutParams();
if (currentLp instanceof ViewGroup.LayoutParams) {
@@ -478,7 +492,7 @@
if (remove) {
View previousView = mViewsMap.get(index).view;
- int oldRelativeIndex = mViewsMap.get(index).index;
+ int oldRelativeIndex = mViewsMap.get(index).relativeIndex;
mPreviousViews.add(index);
transformViewForTransition(oldRelativeIndex, -1, previousView, animate);
@@ -494,7 +508,7 @@
int index = modulo(i, getWindowSize());
int oldRelativeIndex;
if (mViewsMap.containsKey(index)) {
- oldRelativeIndex = mViewsMap.get(index).index;
+ oldRelativeIndex = mViewsMap.get(index).relativeIndex;
} else {
oldRelativeIndex = -1;
}
@@ -507,14 +521,16 @@
if (inOldRange) {
View view = mViewsMap.get(index).view;
- mViewsMap.get(index).index = newRelativeIndex;
+ mViewsMap.get(index).relativeIndex = newRelativeIndex;
applyTransformForChildAtIndex(view, newRelativeIndex);
transformViewForTransition(oldRelativeIndex, newRelativeIndex, view, animate);
// Otherwise this view is new to the window
} else {
// Get the new view from the adapter, add it and apply any transform / animation
- View newView = mAdapter.getView(modulo(i, adapterCount), null, this);
+ final int adapterPosition = modulo(i, adapterCount);
+ View newView = mAdapter.getView(adapterPosition, null, this);
+ long itemId = mAdapter.getItemId(adapterPosition);
// We wrap the new view in a FrameLayout so as to respect the contract
// with the adapter, that is, that we don't modify this view directly
@@ -524,7 +540,8 @@
if (newView != null) {
fl.addView(newView);
}
- mViewsMap.put(index, new ViewAndIndex(fl, newRelativeIndex));
+ mViewsMap.put(index, new ViewAndMetaData(fl, newRelativeIndex,
+ adapterPosition, itemId));
addChild(fl);
applyTransformForChildAtIndex(fl, newRelativeIndex);
transformViewForTransition(-1, newRelativeIndex, fl, animate);
@@ -601,6 +618,7 @@
case MotionEvent.ACTION_UP: {
if (mTouchMode == TOUCH_MODE_DOWN_IN_CURRENT_VIEW) {
final View v = getCurrentView();
+ final ViewAndMetaData viewData = getMetaDataForChild(v);
if (v != null) {
if (isTransformedTouchPointInView(ev.getX(), ev.getY(), v, null)) {
final Handler handler = getHandler();
@@ -613,7 +631,12 @@
hideTapFeedback(v);
post(new Runnable() {
public void run() {
- performItemClick(v, 0, 0);
+ if (viewData != null) {
+ performItemClick(v, viewData.adapterPosition,
+ viewData.itemId);
+ } else {
+ performItemClick(v, 0, 0);
+ }
}
});
}
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index ec4ef4b..71c91e1 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -427,8 +427,8 @@
// Here we need to make sure that the z-order of the children is correct
for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
int index = modulo(i, getWindowSize());
- ViewAndIndex vi = mViewsMap.get(index);
- if (vi != null) {
+ ViewAndMetaData vm = mViewsMap.get(index);
+ if (vm != null) {
View v = mViewsMap.get(index).view;
if (v != null) v.bringToFront();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 2fd58e4..c5eaef9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -372,8 +372,6 @@
if (mViewRoot == null) {
return ERROR_NOT_INFLATED.createResult();
}
- // measure the views
- int w_spec, h_spec;
RenderingMode renderingMode = params.getRenderingMode();
@@ -385,38 +383,64 @@
mMeasuredScreenHeight = params.getScreenHeight();
if (renderingMode != RenderingMode.NORMAL) {
- // measure the full size needed by the layout.
- w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth,
- renderingMode.isHorizExpand() ?
- MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
- : MeasureSpec.EXACTLY);
- h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight,
- renderingMode.isVertExpand() ?
- MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
- : MeasureSpec.EXACTLY);
- mViewRoot.measure(w_spec, h_spec);
+ int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
+ MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
+ : MeasureSpec.EXACTLY;
+ int heightMeasureSpecMode = renderingMode.isVertExpand() ?
+ MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
+ : MeasureSpec.EXACTLY;
+ // We used to compare the measured size of the content to the screen size but
+ // this does not work anymore due to the 2 following issues:
+ // - If the content is in a decor (system bar, title/action bar), the root view
+ // will not resize even with the UNSPECIFIED because of the embedded layout.
+ // - If there is no decor, but a dialog frame, then the dialog padding prevents
+ // comparing the size of the content to the screen frame (as it would not
+ // take into account the dialog padding).
+
+ // The solution is to first get the content size in a normal rendering, inside
+ // the decor or the dialog padding.
+ // Then measure only the content with UNSPECIFIED to see the size difference
+ // and apply this to the screen size.
+
+ // first measure the full layout, with EXACTLY to get the size of the
+ // content as it is inside the decor/dialog
+ Pair<Integer, Integer> exactMeasure = measureView(
+ mViewRoot, mContentRoot.getChildAt(0),
+ mMeasuredScreenWidth, MeasureSpec.EXACTLY,
+ mMeasuredScreenHeight, MeasureSpec.EXACTLY);
+
+ // now measure the content only using UNSPECIFIED (where applicable, based on
+ // the rendering mode). This will give us the size the content needs.
+ Pair<Integer, Integer> result = measureView(
+ mContentRoot, mContentRoot.getChildAt(0),
+ mMeasuredScreenWidth, widthMeasureSpecMode,
+ mMeasuredScreenHeight, heightMeasureSpecMode);
+
+ // now look at the difference and add what is needed.
if (renderingMode.isHorizExpand()) {
- int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth();
- if (neededWidth > mMeasuredScreenWidth) {
- mMeasuredScreenWidth = neededWidth;
+ int measuredWidth = exactMeasure.getFirst();
+ int neededWidth = result.getFirst();
+ if (neededWidth > measuredWidth) {
+ mMeasuredScreenWidth += neededWidth - measuredWidth;
}
}
if (renderingMode.isVertExpand()) {
- int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight();
- if (neededHeight > mMeasuredScreenHeight) {
- mMeasuredScreenHeight = neededHeight;
+ int measuredHeight = exactMeasure.getSecond();
+ int neededHeight = result.getSecond();
+ if (neededHeight > measuredHeight) {
+ mMeasuredScreenHeight += neededHeight - measuredHeight;
}
}
}
}
- // remeasure with the size we need
+ // measure again with the size we need
// This must always be done before the call to layout
- w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, MeasureSpec.EXACTLY);
- h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight, MeasureSpec.EXACTLY);
- mViewRoot.measure(w_spec, h_spec);
+ measureView(mViewRoot, null /*measuredView*/,
+ mMeasuredScreenWidth, MeasureSpec.EXACTLY,
+ mMeasuredScreenHeight, MeasureSpec.EXACTLY);
// now do the layout.
mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
@@ -494,6 +518,34 @@
}
/**
+ * Executes {@link View#measure(int, int)} on a given view with the given parameters (used
+ * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}.
+ *
+ * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height)
+ * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}).
+ *
+ * @param viewToMeasure the view on which to execute measure().
+ * @param measuredView if non null, the view to query for its measured width/height.
+ * @param width the width to use in the MeasureSpec.
+ * @param widthMode the MeasureSpec mode to use for the width.
+ * @param height the height to use in the MeasureSpec.
+ * @param heightMode the MeasureSpec mode to use for the height.
+ * @return the measured width/height if measuredView is non-null, null otherwise.
+ */
+ private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
+ int width, int widthMode, int height, int heightMode) {
+ int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
+ int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
+ viewToMeasure.measure(w_spec, h_spec);
+
+ if (measuredView != null) {
+ return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight());
+ }
+
+ return null;
+ }
+
+ /**
* Animate an object
* <p>
* {@link #acquire(long)} must have been called before this.