Merge "Add white touch feedback drawable to Dialer" into lmp-dev
diff --git a/res/layout-land/quickcontact_activity.xml b/res/layout-land/quickcontact_activity.xml
index 9a07698..b22b5ef 100644
--- a/res/layout-land/quickcontact_activity.xml
+++ b/res/layout-land/quickcontact_activity.xml
@@ -23,19 +23,39 @@
android:focusableInTouchMode="true"
android:descendantFocusability="afterDescendants" >
- <View
- android:layout_width="match_parent"
- android:layout_height="@dimen/quickcontact_starting_empty_height"
- android:contentDescription="@string/quickcontact_transparent_view_description"
- android:id="@+id/transparent_view" />
-
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <include layout="@layout/quickcontact_header" />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/quickcontact_starting_empty_height"
+ android:contentDescription="@string/quickcontact_transparent_view_description"
+ android:id="@+id/transparent_view" />
- <include layout="@layout/quickcontact_content" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <!-- Needs a non null background for elevation to work on this View. This will
+ *not* cause an additional draw since the background is transparent. -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#00000000"
+ android:id="@+id/toolbar_parent">
+
+ <include layout="@layout/quickcontact_header" />
+
+ <include layout="@layout/quickcontact_title" />
+
+ </FrameLayout>
+
+ <include layout="@layout/quickcontact_content" />
+
+ </LinearLayout>
</LinearLayout>
diff --git a/res/layout/quickcontact_activity.xml b/res/layout/quickcontact_activity.xml
index 008062b..577a451 100644
--- a/res/layout/quickcontact_activity.xml
+++ b/res/layout/quickcontact_activity.xml
@@ -24,14 +24,34 @@
android:focusableInTouchMode="true"
android:descendantFocusability="afterDescendants" >
- <View
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="@dimen/quickcontact_starting_empty_height"
- android:contentDescription="@string/quickcontact_transparent_view_description"
- android:id="@+id/transparent_view" />
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <include layout="@layout/quickcontact_header" />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/quickcontact_starting_empty_height"
+ android:contentDescription="@string/quickcontact_transparent_view_description"
+ android:id="@+id/transparent_view" />
- <include layout="@layout/quickcontact_content" />
+ <!-- Needs a non null background for elevation to work on this View. This will *not*
+ cause an additional draw since the background is transparent. -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#00000000"
+ android:id="@+id/toolbar_parent">
+ <include layout="@layout/quickcontact_header" />
+ </FrameLayout>
+
+ <include layout="@layout/quickcontact_content" />
+
+ </LinearLayout>
+
+ <!-- This title's maximum height must be less than the minimum size of its
+ parent ViewGroup because of an oddity in the way View#setScaleY() works. As a result,
+ this title can not be inside @style/quickcontact_header. -->
+ <include layout="@layout/quickcontact_title" />
</com.android.contacts.widget.MultiShrinkScroller>
\ No newline at end of file
diff --git a/res/layout/quickcontact_header.xml b/res/layout/quickcontact_header.xml
index 1f73215..bb89dda 100644
--- a/res/layout/quickcontact_header.xml
+++ b/res/layout/quickcontact_header.xml
@@ -14,15 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<!-- Needs a non null background in for elevation to work on this View. This will *not* cause an
- additional draw since the background is transparent. -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#00000000"
- android:id="@+id/toolbar_parent">
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.android.contacts.widget.QuickContactImageView
android:id="@+id/photo"
@@ -61,17 +53,4 @@
android:background="#00000000"
android:id="@+id/toolbar"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/actionbar_text_color"
- android:maxLines="@integer/quickcontact_title_lines"
- android:ellipsize="end"
- android:layout_gravity="bottom|start"
- android:textSize="@dimen/quickcontact_maximum_title_size"
- android:layout_marginStart="@dimen/quickcontact_title_initial_margin"
- android:layout_marginEnd="@dimen/quickcontact_title_initial_margin"
- android:layout_marginBottom="@dimen/quickcontact_title_initial_margin"
- android:id="@+id/large_title"/>
-
-</FrameLayout>
+</merge>
diff --git a/res/layout/quickcontact_title.xml b/res/layout/quickcontact_title.xml
new file mode 100644
index 0000000..9b23a86
--- /dev/null
+++ b/res/layout/quickcontact_title.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/quickcontact_title_initial_margin"
+ android:layout_marginEnd="@dimen/quickcontact_title_initial_margin"
+ android:layout_marginBottom="@dimen/quickcontact_title_initial_margin"
+ android:layout_gravity="top|start"
+ android:textColor="@color/actionbar_text_color"
+ android:maxLines="@integer/quickcontact_title_lines"
+ android:textSize="@dimen/quickcontact_maximum_title_size"
+ android:ellipsize="end"
+ android:id="@+id/large_title"/>
\ No newline at end of file
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 495526d..827c71b 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -21,4 +21,9 @@
<dimen name="quick_contact_photo_container_height">360dip</dimen>
<dimen name="contact_picker_contact_list_min_height">650dip</dimen>
<dimen name="list_visible_scrollbar_padding">48dip</dimen>
+
+ <!-- When QC is uncollapsed, the title has this much margin on its left, right and bottom -->
+ <dimen name="quickcontact_title_initial_margin">32dp</dimen>
+ <!-- Initial size of QuickContact's title size -->
+ <dimen name="quickcontact_maximum_title_size">64dp</dimen>
</resources>
diff --git a/src/com/android/contacts/widget/MultiShrinkScroller.java b/src/com/android/contacts/widget/MultiShrinkScroller.java
index 370c3ae..632bb28 100644
--- a/src/com/android/contacts/widget/MultiShrinkScroller.java
+++ b/src/com/android/contacts/widget/MultiShrinkScroller.java
@@ -24,6 +24,7 @@
import android.util.TypedValue;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -31,6 +32,7 @@
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
import android.widget.EdgeEffect;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -51,7 +53,7 @@
* features are missing. For example: handling of KEYCODES, OverScroll bounce and saving
* scroll state in savedInstanceState bundles.
*/
-public class MultiShrinkScroller extends LinearLayout {
+public class MultiShrinkScroller extends FrameLayout {
/**
* 1000 pixels per millisecond. Ie, 1 pixel per second.
@@ -147,6 +149,9 @@
0, 0, 0, 1, 0
};
+ private final PathInterpolator mTextSizePathInterpolator
+ = new PathInterpolator(0.16f, 0.4f, 0.2f, 1);
+
private final int[] mGradientColors = new int[] {0,0xAA000000};
private GradientDrawable mTitleGradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, mGradientColors);
@@ -287,18 +292,28 @@
mMaximumHeaderHeight = getHeight();
mMinimumHeaderHeight = mMaximumHeaderHeight;
mIntermediateHeaderHeight = mMaximumHeaderHeight;
+
+ // Permanently set photo width and height.
final TypedValue photoRatio = new TypedValue();
getResources().getValue(R.vals.quickcontact_photo_ratio, photoRatio,
/* resolveRefs = */ true);
- final LayoutParams layoutParams
- = (LayoutParams) mPhotoViewContainer.getLayoutParams();
- layoutParams.height = mMaximumHeaderHeight;
- layoutParams.width = (int) (mMaximumHeaderHeight * photoRatio.getFloat());
- mPhotoViewContainer.setLayoutParams(layoutParams);
+ final ViewGroup.LayoutParams photoLayoutParams
+ = mPhotoViewContainer.getLayoutParams();
+ photoLayoutParams.height = mMaximumHeaderHeight;
+ photoLayoutParams.width = (int) (mMaximumHeaderHeight * photoRatio.getFloat());
+ mPhotoViewContainer.setLayoutParams(photoLayoutParams);
+
+ // Permanently set title width and margin.
+ final FrameLayout.LayoutParams largeTextLayoutParams
+ = (FrameLayout.LayoutParams) mLargeTextView.getLayoutParams();
+ largeTextLayoutParams.width = photoLayoutParams.width -
+ largeTextLayoutParams.leftMargin - largeTextLayoutParams.rightMargin;
+ largeTextLayoutParams.gravity = Gravity.BOTTOM | Gravity.START;
+ mLargeTextView.setLayoutParams(largeTextLayoutParams);
}
calculateCollapsedLargeTitlePadding();
- updateHeaderTextSize();
+ updateHeaderTextSizeAndMargin();
configureGradientViewHeights();
}
});
@@ -578,7 +593,7 @@
scrollDown(delta);
}
updatePhotoTintAndDropShadow();
- updateHeaderTextSize();
+ updateHeaderTextSizeAndMargin();
final boolean isFullscreen = getScrollNeededToBeFullScreen() <= 0;
mHasEverTouchedTheTop |= isFullscreen;
if (mListener != null) {
@@ -596,13 +611,13 @@
*/
@NeededForReflection
public void setToolbarHeight(int delta) {
- final LinearLayout.LayoutParams toolbarLayoutParams
- = (LayoutParams) mToolbar.getLayoutParams();
+ final ViewGroup.LayoutParams toolbarLayoutParams
+ = mToolbar.getLayoutParams();
toolbarLayoutParams.height = delta;
mToolbar.setLayoutParams(toolbarLayoutParams);
updatePhotoTintAndDropShadow();
- updateHeaderTextSize();
+ updateHeaderTextSizeAndMargin();
}
@NeededForReflection
@@ -615,12 +630,12 @@
*/
@NeededForReflection
public void setHeaderHeight(int height) {
- final LinearLayout.LayoutParams toolbarLayoutParams
- = (LayoutParams) mToolbar.getLayoutParams();
+ final ViewGroup.LayoutParams toolbarLayoutParams
+ = mToolbar.getLayoutParams();
toolbarLayoutParams.height = height;
mToolbar.setLayoutParams(toolbarLayoutParams);
updatePhotoTintAndDropShadow();
- updateHeaderTextSize();
+ updateHeaderTextSizeAndMargin();
}
@NeededForReflection
@@ -639,10 +654,8 @@
*/
@NeededForReflection
public int getScroll() {
- final LinearLayout.LayoutParams toolbarLayoutParams
- = (LayoutParams) mToolbar.getLayoutParams();
return mTransparentStartHeight - getTransparentViewHeight()
- + getMaximumScrollableHeaderHeight() - toolbarLayoutParams.height
+ + getMaximumScrollableHeaderHeight() - getToolbarHeight()
+ mScrollView.getScrollY();
}
@@ -662,10 +675,8 @@
* This value should never be used in conjunction with {@link #getScroll} values.
*/
private int getScroll_ignoreOversizedHeaderForSnapping() {
- final LinearLayout.LayoutParams toolbarLayoutParams
- = (LayoutParams) mToolbar.getLayoutParams();
return mTransparentStartHeight - getTransparentViewHeight()
- + Math.max(getMaximumScrollableHeaderHeight() - toolbarLayoutParams.height, 0)
+ + Math.max(getMaximumScrollableHeaderHeight() - getToolbarHeight(), 0)
+ mScrollView.getScrollY();
}
@@ -787,8 +798,8 @@
setTransparentViewHeight(Math.max(0, getTransparentViewHeight()));
delta -= originalValue - getTransparentViewHeight();
}
- final LinearLayout.LayoutParams toolbarLayoutParams
- = (LayoutParams) mToolbar.getLayoutParams();
+ final ViewGroup.LayoutParams toolbarLayoutParams
+ = mToolbar.getLayoutParams();
if (toolbarLayoutParams.height > getFullyCompressedHeaderHeight()) {
final int originalValue = toolbarLayoutParams.height;
toolbarLayoutParams.height -= delta;
@@ -823,8 +834,7 @@
mScrollView.scrollBy(0, delta);
delta -= mScrollView.getScrollY() - originalValue;
}
- final LinearLayout.LayoutParams toolbarLayoutParams
- = (LayoutParams) mToolbar.getLayoutParams();
+ final ViewGroup.LayoutParams toolbarLayoutParams = mToolbar.getLayoutParams();
if (toolbarLayoutParams.height < getMaximumScrollableHeaderHeight()) {
final int originalValue = toolbarLayoutParams.height;
toolbarLayoutParams.height -= delta;
@@ -852,9 +862,9 @@
/**
* Set the header size and padding, based on the current scroll position.
*/
- private void updateHeaderTextSize() {
+ private void updateHeaderTextSizeAndMargin() {
if (mIsTwoPanel) {
- // The text size stays constant on two panel layouts.
+ // The text size stays at a constant size & location in two panel layouts.
return;
}
@@ -866,25 +876,25 @@
}
mLargeTextView.setPivotY(mLargeTextView.getHeight() / 2);
- final int START_TEXT_SCALING_THRESHOLD_COEFFICIENT = 2;
- final int threshold = START_TEXT_SCALING_THRESHOLD_COEFFICIENT * mMinimumHeaderHeight;
final int toolbarHeight = mToolbar.getLayoutParams().height;
- if (toolbarHeight >= threshold) {
- // Keep the text at maximum size since the header is smaller than threshold.
+ if (toolbarHeight >= mMaximumHeaderHeight) {
+ // Everything is full size when the header is fully expanded.
mLargeTextView.setScaleX(1);
mLargeTextView.setScaleY(1);
- setInterpolatedTitleMargin(1);
+ setInterpolatedTitleMargins(1);
return;
}
- final float ratio = (toolbarHeight - mMinimumHeaderHeight)
- / (float)(threshold - mMinimumHeaderHeight);
+
+ float ratio = (toolbarHeight - mMinimumHeaderHeight)
+ / (float)(mMaximumHeaderHeight - mMinimumHeaderHeight);
final float minimumSize = mInvisiblePlaceholderTextView.getHeight();
- final float scale = (minimumSize + (mMaximumHeaderTextSize - minimumSize) * ratio)
+ final float bezierOutput = mTextSizePathInterpolator.getInterpolation(ratio);
+ float scale = (minimumSize + (mMaximumHeaderTextSize - minimumSize) * bezierOutput)
/ mMaximumHeaderTextSize;
mLargeTextView.setScaleX(scale);
mLargeTextView.setScaleY(scale);
- setInterpolatedTitleMargin(ratio);
+ setInterpolatedTitleMargins(bezierOutput);
}
/**
@@ -917,14 +927,21 @@
* Interpolate the title's margin size. When {@param x}=1, use the maximum title margins.
* When {@param x}=0, use the margin values taken from {@link #mInvisiblePlaceholderTextView}.
*/
- private void setInterpolatedTitleMargin(float x) {
- final FrameLayout.LayoutParams layoutParams
+ private void setInterpolatedTitleMargins(float x) {
+ final FrameLayout.LayoutParams titleLayoutParams
= (FrameLayout.LayoutParams) mLargeTextView.getLayoutParams();
- layoutParams.bottomMargin = (int) (mCollapsedTitleBottomMargin * (1 - x)
- + mMaximumTitleMargin * x) ;
- layoutParams.setMarginStart((int) (mCollapsedTitleStartMargin * (1 - x)
+ final LinearLayout.LayoutParams toolbarLayoutParams
+ = (LinearLayout.LayoutParams) mToolbar.getLayoutParams();
+ titleLayoutParams.setMarginStart((int) (mCollapsedTitleStartMargin * (1 - x)
+ mMaximumTitleMargin * x));
- mLargeTextView.setLayoutParams(layoutParams);
+ // How offset the title should be from the bottom of the toolbar
+ final int pretendBottomMargin = (int) (mCollapsedTitleBottomMargin * (1 - x)
+ + mMaximumTitleMargin * x) ;
+ // Calculate how offset the title should be from the top of the screen.
+ titleLayoutParams.topMargin = getTransparentViewHeight()
+ + toolbarLayoutParams.height - pretendBottomMargin
+ - mLargeTextView.getHeight();
+ mLargeTextView.setLayoutParams(titleLayoutParams);
}
private void updatePhotoTintAndDropShadow() {
@@ -943,7 +960,7 @@
// We need to use toolbarLayoutParams to determine the height, since the layout
// params can be updated before the height change is reflected inside the View#getHeight().
- final int toolbarHeight = mToolbar.getLayoutParams().height;
+ final int toolbarHeight = getToolbarHeight();
if (toolbarHeight <= mMinimumHeaderHeight && !mIsTwoPanel) {
mPhotoViewContainer.setElevation(mToolbarElevation);
@@ -1139,7 +1156,7 @@
final int newEmptyScrollViewSpace = -getOverflowingChildViewSize() + heightDelta;
if (newEmptyScrollViewSpace > 0 && !mIsTwoPanel) {
- final int newDesiredToolbarHeight = Math.min(mToolbar.getLayoutParams().height
+ final int newDesiredToolbarHeight = Math.min(getToolbarHeight()
+ newEmptyScrollViewSpace, getMaximumScrollableHeaderHeight());
ObjectAnimator.ofInt(this, "toolbarHeight", newDesiredToolbarHeight).setDuration(
ExpandingEntryCardView.DURATION_COLLAPSE_ANIMATION_CHANGE_BOUNDS).start();