Merge "Fix build."
diff --git a/res/layout/conversation_message_details_header.xml b/res/layout/conversation_message_details_header.xml
index 4a7f5b4..0500e4b 100644
--- a/res/layout/conversation_message_details_header.xml
+++ b/res/layout/conversation_message_details_header.xml
@@ -15,32 +15,25 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <LinearLayout
- android:id="@+id/details_collapsed_content"
- android:layout_width="match_parent"
- android:layout_height="@dimen/message_details_header_collapsed_height"
- android:background="?android:attr/selectableItemBackground"
- android:paddingLeft="@dimen/message_details_header_padding_left"
- android:paddingRight="@dimen/message_details_header_padding_right"
- android:gravity="center_vertical">
- <TextView
- android:id="@+id/recipients_summary"
- android:layout_weight="1"
- android:layout_marginRight="16dip"
- android:singleLine="true"
- android:bufferType="spannable"
- style="@style/MessageHeaderSmallStyle" />
- <TextView
- android:id="@+id/date_summary"
- android:lines="1"
- style="@style/MessageHeaderDateTextStyle" />
- <ImageView
- style="@style/MessageHeaderExpanderMinimizedStyle" />
- </LinearLayout>
- <View
- android:id="@+id/details_bottom_border"
- android:layout_width="match_parent"
- android:layout_height="@dimen/message_details_header_bottom_border_height"
- android:background="@color/conv_subject_border" />
-</merge>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/details_collapsed_content"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/message_details_header_collapsed_height"
+ android:background="?android:attr/selectableItemBackground"
+ android:paddingLeft="@dimen/message_details_header_padding_left"
+ android:paddingRight="@dimen/message_details_header_padding_right"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/recipients_summary"
+ android:layout_weight="1"
+ android:layout_marginRight="16dip"
+ android:singleLine="true"
+ android:bufferType="spannable"
+ style="@style/MessageHeaderSmallStyle" />
+ <TextView
+ android:id="@+id/date_summary"
+ android:lines="1"
+ style="@style/MessageHeaderDateTextStyle" />
+ <ImageView
+ style="@style/MessageHeaderExpanderMinimizedStyle" />
+</LinearLayout>
diff --git a/res/layout/conversation_message_header.xml b/res/layout/conversation_message_header.xml
index dcb370b..d14df48 100644
--- a/res/layout/conversation_message_header.xml
+++ b/res/layout/conversation_message_header.xml
@@ -27,4 +27,11 @@
<include layout="@layout/conversation_message_upper_header"
android:id="@+id/upper_header" />
+ <View
+ android:id="@+id/details_bottom_border"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/message_details_header_bottom_border_height"
+ android:visibility="gone"
+ android:background="@color/conv_subject_border" />
+
</com.android.mail.browse.MessageHeaderView>
diff --git a/src/com/android/mail/browse/ConversationContainer.java b/src/com/android/mail/browse/ConversationContainer.java
index 1aeb4c6..e563bdd 100644
--- a/src/com/android/mail/browse/ConversationContainer.java
+++ b/src/com/android/mail/browse/ConversationContainer.java
@@ -17,8 +17,6 @@
package com.android.mail.browse;
-import com.google.common.collect.Sets;
-
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -35,6 +33,7 @@
import com.android.mail.browse.ScrollNotifier.ScrollListener;
import com.android.mail.utils.DequeMap;
import com.android.mail.utils.LogUtils;
+import com.google.common.collect.Sets;
import java.util.Set;
@@ -338,13 +337,22 @@
}
/**
+ * Executes a measure pass over the specified child overlay view and returns the measured
+ * height. The measurement uses whatever the current container's width measure spec is.
+ * This method ignores view visibility and returns the height that the view would be if visible.
+ *
+ * @param overlayView an overlay view to measure. does not actually have to be attached yet.
+ * @return height that the view would be if it was visible
+ */
+ public int measureOverlay(View overlayView) {
+ measureOverlayView(overlayView);
+ return overlayView.getMeasuredHeight();
+ }
+
+ /**
* Copied/stolen from {@link ListView}.
*/
- private void measureItem(View child) {
- if (child.getVisibility() == GONE) {
- return;
- }
-
+ private void measureOverlayView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(
@@ -429,14 +437,8 @@
}
mWidthMeasureSpec = widthMeasureSpec;
- // Need to measure children in case this layout pass was triggered by a child layout change.
- // TODO: restrict child measurement to just that case.
- for (int i = 0, overlayCount = getOverlayCount(); i < overlayCount; i++) {
- final View overlayView = getOverlayAt(i);
- if (overlayView.getVisibility() != GONE) {
- measureItem(overlayView);
- }
- }
+ // onLayout will re-measure and re-position overlays for the new container size, but the
+ // spacer offsets would still need to be updated to have them draw at their new locations.
}
@Override
@@ -447,6 +449,12 @@
positionOverlays(0, mOffsetY);
}
+ @Override
+ public void requestLayout() {
+ // Suppress layouts requested by children. Overlays don't push on each other, and WebView
+ // doesn't change its layout.
+ }
+
private int getOverlayBottom(int spacerIndex) {
// TODO: round or truncate?
return (int) (mOverlayBottoms[spacerIndex] * mScale);
@@ -454,24 +462,34 @@
private void positionOverlay(int adapterIndex, int overlayTopY, int overlayBottomY) {
View overlayView = findExistingOverlayView(adapterIndex);
- final int itemType = mOverlayAdapter.getItemViewType(adapterIndex);
+ final ConversationItem item = mOverlayAdapter.getItem(adapterIndex);
+
// is the overlay visible and does it have non-zero height?
if (overlayTopY != overlayBottomY && overlayBottomY > mOffsetY
&& overlayTopY < mOffsetY + getHeight()) {
// show and/or move overlay
if (overlayView == null) {
overlayView = addOverlayView(adapterIndex);
- measureItem(overlayView);
- traceLayout("show overlay %d", adapterIndex);
+ measureOverlayView(overlayView);
+ item.markMeasurementValid();
+ traceLayout("show/measure overlay %d", adapterIndex);
} else {
traceLayout("move overlay %d", adapterIndex);
+ if (!item.isMeasurementValid()) {
+ measureOverlayView(overlayView);
+ item.markMeasurementValid();
+ traceLayout("and (re)measure overlay %d, old/new heights=%d/%d", adapterIndex,
+ overlayView.getHeight(), overlayView.getMeasuredHeight());
+ }
}
+ traceLayout("laying out overlay %d with h=%d", adapterIndex,
+ overlayView.getMeasuredHeight());
layoutOverlay(overlayView, overlayTopY);
} else {
// hide overlay
if (overlayView != null) {
traceLayout("hide overlay %d", adapterIndex);
- onOverlayScrolledOff(overlayView, itemType, overlayTopY, overlayBottomY);
+ onOverlayScrolledOff(overlayView, item.getType(), overlayTopY, overlayBottomY);
} else {
traceLayout("ignore non-visible overlay %d", adapterIndex);
}
@@ -485,10 +503,6 @@
// layout an existing view
// need its top offset into the conversation, its height, and the scroll offset
private void layoutOverlay(View child, int childTop, int childBottom) {
- if (child.getVisibility() == GONE) {
- return;
- }
-
final int top = childTop - mOffsetY;
final int bottom = childBottom - mOffsetY;
child.layout(0, top, child.getMeasuredWidth(), bottom);
diff --git a/src/com/android/mail/browse/ConversationViewAdapter.java b/src/com/android/mail/browse/ConversationViewAdapter.java
index 282e39e..2d09d22 100644
--- a/src/com/android/mail/browse/ConversationViewAdapter.java
+++ b/src/com/android/mail/browse/ConversationViewAdapter.java
@@ -35,7 +35,6 @@
import com.android.mail.providers.Message;
import com.android.mail.providers.UIProvider;
import com.android.mail.utils.LogUtils;
-import com.android.mail.utils.Utils;
import com.google.common.collect.Lists;
import java.util.List;
@@ -73,6 +72,7 @@
public static abstract class ConversationItem {
private int mHeight; // in px
+ private boolean mNeedsMeasure;
/**
* @see Adapter#getItemViewType(int)
@@ -96,15 +96,6 @@
public abstract boolean isContiguous();
/**
- * Measure the expected visible height of the overlay view. Even if the view is initially
- * GONE, this method must return whatever height the view is going to be when it is later
- * made VISIBLE.
- */
- public int measureHeight(View v, ViewGroup parent) {
- return Utils.measureViewHeight(v, parent);
- }
-
- /**
* This method's behavior is critical and requires some 'splainin.
* <p>
* Subclasses that return a zero-size height to the {@link ConversationContainer} will
@@ -120,7 +111,22 @@
public void setHeight(int h) {
LogUtils.i(LOG_TAG, "IN setHeight=%dpx of overlay item: %s", h, this);
- mHeight = h;
+ if (mHeight != h) {
+ mHeight = h;
+ mNeedsMeasure = true;
+ }
+ }
+
+ public boolean isMeasurementValid() {
+ return !mNeedsMeasure;
+ }
+
+ public void markMeasurementValid() {
+ mNeedsMeasure = false;
+ }
+
+ public void invalidateMeasurement() {
+ mNeedsMeasure = true;
}
}
diff --git a/src/com/android/mail/browse/ConversationViewHeader.java b/src/com/android/mail/browse/ConversationViewHeader.java
index 1ff04ba..1fdf732 100644
--- a/src/com/android/mail/browse/ConversationViewHeader.java
+++ b/src/com/android/mail/browse/ConversationViewHeader.java
@@ -169,11 +169,6 @@
}
}
- public int getPremeasuredHeight() {
- ViewGroup parent = (ViewGroup) getParent();
- return Utils.measureViewHeight(this, parent);
- }
-
@Override
public void onClick(View v) {
if (R.id.folders == v.getId()) {
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index 8187942..d9c3259 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -83,6 +83,7 @@
private MessageHeaderViewCallbacks mCallbacks;
+ private ViewGroup mUpperHeaderView;
private TextView mSenderNameView;
private TextView mSenderEmailView;
private QuickContactBadge mPhotoView;
@@ -185,6 +186,7 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ mUpperHeaderView = (ViewGroup) findViewById(R.id.upper_header);
mSenderNameView = (TextView) findViewById(R.id.sender_name);
mSenderEmailView = (TextView) findViewById(R.id.sender_email);
mPhotoView = (QuickContactBadge) findViewById(R.id.photo);
@@ -196,6 +198,8 @@
mTitleContainerCollapsedMarginRight = ((MarginLayoutParams) mTitleContainerView
.getLayoutParams()).rightMargin;
+ mBottomBorderView = findViewById(R.id.details_bottom_border);
+
setExpanded(true);
registerMessageClickTargets(R.id.reply, R.id.reply_all, R.id.forward, R.id.star,
@@ -939,20 +943,9 @@
*/
private void showCollapsedDetails() {
if (mCollapsedDetailsView == null) {
- // Collapsed details is a merge layout that also contains the bottom
- // border. The
- // assumption is that collapsed is inflated before expanded. If we
- // ever change this
- // so either may be inflated first, the bottom border should be
- // moved out into a
- // separate layout and inflated alongside either collapsed or
- // expanded, whichever is
- // first.
- mInflater.inflate(R.layout.conversation_message_details_header, this);
-
- mBottomBorderView = findViewById(R.id.details_bottom_border);
- mCollapsedDetailsView = (ViewGroup) findViewById(R.id.details_collapsed_content);
-
+ mCollapsedDetailsView = (ViewGroup) mInflater.inflate(
+ R.layout.conversation_message_details_header, this, false);
+ addView(mCollapsedDetailsView, indexOfChild(mUpperHeaderView) + 1);
mCollapsedDetailsView.setOnClickListener(this);
}
if (!mCollapsedDetailsValid) {
@@ -976,14 +969,7 @@
if (mExpandedDetailsView == null) {
View v = mInflater.inflate(R.layout.conversation_message_details_header_expanded,
this, false);
-
- // Insert expanded details into the parent linear layout immediately
- // after the
- // previously inflated collapsed details view, and above any other
- // optional views
- // like 'show pictures' or attachments.
- // we assume collapsed has been inflated by now
- addView(v, indexOfChild(mCollapsedDetailsView) + 1);
+ addView(v, indexOfChild(mUpperHeaderView) + 1);
v.setOnClickListener(this);
mExpandedDetailsView = (ViewGroup) v;
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 1f3ba50..aa2a1be 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -405,8 +405,9 @@
mConversationContainer.addScrapView(type, hostView);
}
- final int heightPx = convItem.measureHeight(hostView, mConversationContainer);
+ final int heightPx = mConversationContainer.measureOverlay(hostView);
convItem.setHeight(heightPx);
+ convItem.markMeasurementValid();
return (int) (heightPx / mDensity);
}