Merge "Keep RemoteInputView visible when focused" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
046f2c80ae
@@ -21,7 +21,7 @@
|
||||
<com.android.internal.widget.NotificationActionListLayout
|
||||
android:id="@+id/actions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_height="@dimen/notification_action_list_height"
|
||||
android:paddingEnd="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
|
||||
@@ -152,6 +152,9 @@
|
||||
<!-- The margin on the end of the content view with a picture.-->
|
||||
<dimen name="notification_content_picture_margin">56dp</dimen>
|
||||
|
||||
<!-- The height of the notification action list -->
|
||||
<dimen name="notification_action_list_height">56dp</dimen>
|
||||
|
||||
<!-- height of the content margin to accomodate for the header -->
|
||||
<dimen name="notification_content_margin_top">37.5dp</dimen>
|
||||
|
||||
|
||||
@@ -2584,6 +2584,8 @@
|
||||
<java-symbol type="dimen" name="input_extract_action_button_width" />
|
||||
<java-symbol type="dimen" name="input_extract_action_button_height" />
|
||||
|
||||
<java-symbol type="dimen" name="notification_action_list_height" />
|
||||
|
||||
<!-- TV Remote Service package -->
|
||||
<java-symbol type="string" name="config_tvRemoteServicePackage" />
|
||||
|
||||
|
||||
@@ -374,10 +374,42 @@ public class NotificationContentView extends FrameLayout {
|
||||
mContentHeight = Math.max(Math.min(contentHeight, getHeight()), getMinHeight());;
|
||||
mUnrestrictedContentHeight = Math.max(contentHeight, getMinHeight());
|
||||
selectLayout(mAnimate /* animate */, false /* force */);
|
||||
|
||||
int minHeightHint = getMinContentHeightHint();
|
||||
|
||||
NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType);
|
||||
if (wrapper != null) {
|
||||
wrapper.setContentHeight(mContentHeight, minHeightHint);
|
||||
}
|
||||
|
||||
wrapper = getVisibleWrapper(mTransformationStartVisibleType);
|
||||
if (wrapper != null) {
|
||||
wrapper.setContentHeight(mContentHeight, minHeightHint);
|
||||
}
|
||||
|
||||
updateClipping();
|
||||
invalidateOutline();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum apparent height that the wrapper should allow for the purpose
|
||||
* of aligning elements at the bottom edge. If this is larger than the content
|
||||
* height, the notification is clipped instead of being further shrunk.
|
||||
*/
|
||||
private int getMinContentHeightHint() {
|
||||
if (mIsChildInGroup && (mVisibleType == VISIBLE_TYPE_SINGLELINE
|
||||
|| mTransformationStartVisibleType == VISIBLE_TYPE_SINGLELINE)) {
|
||||
return mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.notification_action_list_height);
|
||||
}
|
||||
if (mHeadsUpChild != null) {
|
||||
return mHeadsUpChild.getHeight();
|
||||
} else {
|
||||
return mContractedChild.getHeight() + mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.notification_action_list_height);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContentTransformation() {
|
||||
int visibleType = calculateVisibleType();
|
||||
if (visibleType != mVisibleType) {
|
||||
@@ -493,11 +525,15 @@ public class NotificationContentView extends FrameLayout {
|
||||
} else {
|
||||
int visibleType = calculateVisibleType();
|
||||
if (visibleType != mVisibleType || force) {
|
||||
View visibleView = getViewForVisibleType(visibleType);
|
||||
if (visibleView != null) {
|
||||
visibleView.setVisibility(VISIBLE);
|
||||
transferRemoteInputFocus(visibleType);
|
||||
}
|
||||
View visibleView = getViewForVisibleType(visibleType);
|
||||
if (visibleView != null) {
|
||||
visibleView.setVisibility(VISIBLE);
|
||||
transferRemoteInputFocus(visibleType);
|
||||
}
|
||||
NotificationViewWrapper visibleWrapper = getVisibleWrapper(visibleType);
|
||||
if (visibleWrapper != null) {
|
||||
visibleWrapper.setContentHeight(mContentHeight, getMinContentHeightHint());
|
||||
}
|
||||
|
||||
if (animate && ((visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null)
|
||||
|| (visibleType == VISIBLE_TYPE_HEADSUP && mHeadsUpChild != null)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification;
|
||||
|
||||
import android.text.Layout;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pools;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* A transform state of the action list
|
||||
*/
|
||||
public class ActionListTransformState extends TransformState {
|
||||
|
||||
private static Pools.SimplePool<ActionListTransformState> sInstancePool
|
||||
= new Pools.SimplePool<>(40);
|
||||
|
||||
@Override
|
||||
protected boolean sameAs(TransformState otherState) {
|
||||
return otherState instanceof ActionListTransformState;
|
||||
}
|
||||
|
||||
public static ActionListTransformState obtain() {
|
||||
ActionListTransformState instance = sInstancePool.acquire();
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
}
|
||||
return new ActionListTransformState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resetTransformedView() {
|
||||
// We need to keep the Y transformation, because this is used to keep the action list
|
||||
// aligned at the bottom, unrelated to transforms.
|
||||
float y = getTransformedView().getTranslationY();
|
||||
super.resetTransformedView();
|
||||
getTransformedView().setTranslationY(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
super.recycle();
|
||||
sInstancePool.release(this);
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,10 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
|
||||
private ProgressBar mProgressBar;
|
||||
private TextView mTitle;
|
||||
private TextView mText;
|
||||
private View mActionsContainer;
|
||||
|
||||
private int mContentHeight;
|
||||
private int mMinHeightHint;
|
||||
|
||||
protected NotificationTemplateViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
|
||||
super(ctx, view, row);
|
||||
@@ -123,6 +127,7 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
|
||||
// It's still a viewstub
|
||||
mProgressBar = null;
|
||||
}
|
||||
mActionsContainer = mView.findViewById(com.android.internal.R.id.actions_container);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -225,4 +230,21 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
|
||||
(int) (gSource * (1f - t) + gTarget * t),
|
||||
(int) (bSource * (1f - t) + bTarget * t));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentHeight(int contentHeight, int minHeightHint) {
|
||||
super.setContentHeight(contentHeight, minHeightHint);
|
||||
|
||||
mContentHeight = contentHeight;
|
||||
mMinHeightHint = minHeightHint;
|
||||
updateActionOffset();
|
||||
}
|
||||
|
||||
private void updateActionOffset() {
|
||||
if (mActionsContainer != null) {
|
||||
// We should never push the actions higher than they are in the headsup view.
|
||||
int constrainedContentHeight = Math.max(mContentHeight, mMinHeightHint);
|
||||
mActionsContainer.setTranslationY(constrainedContentHeight - mView.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,4 +158,7 @@ public abstract class NotificationViewWrapper implements TransformableView {
|
||||
|
||||
public void setShowingLegacyBackground(boolean showing) {
|
||||
}
|
||||
|
||||
public void setContentHeight(int contentHeight, int minHeightHint) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,6 +374,11 @@ public class TransformState {
|
||||
result.initFrom(view);
|
||||
return result;
|
||||
}
|
||||
if (view.getId() == com.android.internal.R.id.actions_container) {
|
||||
ActionListTransformState result = ActionListTransformState.obtain();
|
||||
result.initFrom(view);
|
||||
return result;
|
||||
}
|
||||
if (view instanceof NotificationHeaderView) {
|
||||
HeaderTransformState result = HeaderTransformState.obtain();
|
||||
result.initFrom(view);
|
||||
@@ -467,7 +472,7 @@ public class TransformState {
|
||||
resetTransformedView();
|
||||
}
|
||||
|
||||
private void resetTransformedView() {
|
||||
protected void resetTransformedView() {
|
||||
mTransformedView.setTranslationX(0);
|
||||
mTransformedView.setTranslationY(0);
|
||||
mTransformedView.setScaleX(1.0f);
|
||||
|
||||
@@ -272,7 +272,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
||||
|
||||
public boolean requestScrollTo() {
|
||||
findScrollContainer();
|
||||
mScrollContainer.scrollTo(mScrollContainerChild);
|
||||
mScrollContainer.lockScrollTo(mScrollContainerChild);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,6 +243,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
= new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
updateForcedScroll();
|
||||
updateChildren();
|
||||
mChildrenUpdateRequested = false;
|
||||
getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
@@ -334,6 +335,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
private boolean mDrawBackgroundAsSrc;
|
||||
private boolean mFadedOut;
|
||||
private boolean mGroupExpandedForMeasure;
|
||||
private View mForcedScroll;
|
||||
private float mBackgroundFadeAmount = 1.0f;
|
||||
private static final Property<NotificationStackScrollLayout, Float> BACKGROUND_FADE =
|
||||
new FloatProperty<NotificationStackScrollLayout>("backgroundFade") {
|
||||
@@ -591,6 +593,23 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
clampScrollPosition();
|
||||
}
|
||||
|
||||
private void updateForcedScroll() {
|
||||
if (mForcedScroll != null && (!mForcedScroll.hasFocus()
|
||||
|| !mForcedScroll.isAttachedToWindow())) {
|
||||
mForcedScroll = null;
|
||||
}
|
||||
if (mForcedScroll != null) {
|
||||
ExpandableView expandableView = (ExpandableView) mForcedScroll;
|
||||
int positionInLinearLayout = getPositionInLinearLayout(expandableView);
|
||||
int targetScroll = targetScrollForView(expandableView, positionInLinearLayout);
|
||||
|
||||
targetScroll = Math.max(0, Math.min(targetScroll, getScrollRange()));
|
||||
if (mOwnScrollY < targetScroll || positionInLinearLayout < mOwnScrollY) {
|
||||
mOwnScrollY = targetScroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void requestChildrenUpdate() {
|
||||
if (!mChildrenUpdateRequested) {
|
||||
getViewTreeObserver().addOnPreDrawListener(mChildrenUpdater);
|
||||
@@ -978,11 +997,19 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mScrollingEnabled = enable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockScrollTo(View v) {
|
||||
if (mForcedScroll == v) {
|
||||
return;
|
||||
}
|
||||
mForcedScroll = v;
|
||||
scrollTo(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrollTo(View v) {
|
||||
ExpandableView expandableView = (ExpandableView) v;
|
||||
int positionInLinearLayout = getPositionInLinearLayout(v);
|
||||
int targetScroll = positionInLinearLayout + expandableView.getIntrinsicHeight() +
|
||||
getImeInset() - getHeight() + getTopPadding();
|
||||
int targetScroll = targetScrollForView(expandableView, getPositionInLinearLayout(v));
|
||||
|
||||
if (mOwnScrollY < targetScroll) {
|
||||
mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScroll - mOwnScrollY);
|
||||
@@ -993,6 +1020,15 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the scroll necessary to make the bottom edge of {@param v} align with the top of
|
||||
* the IME.
|
||||
*/
|
||||
private int targetScrollForView(ExpandableView v, int positionInLinearLayout) {
|
||||
return positionInLinearLayout + v.getIntrinsicHeight() +
|
||||
getImeInset() - getHeight() + getTopPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
||||
mBottomInset = insets.getSystemWindowInsetBottom();
|
||||
@@ -1111,6 +1147,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
if (ev.getY() < mQsContainer.getBottom()) {
|
||||
return false;
|
||||
}
|
||||
mForcedScroll = null;
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
@@ -2786,6 +2823,14 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearChildFocus(View child) {
|
||||
super.clearChildFocus(child);
|
||||
if (mForcedScroll == child) {
|
||||
mForcedScroll = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDisallowLongPress() {
|
||||
removeLongPressCallback();
|
||||
|
||||
@@ -35,6 +35,12 @@ public interface ScrollContainer {
|
||||
*/
|
||||
boolean scrollTo(View v);
|
||||
|
||||
/**
|
||||
* Like {@link #scrollTo(View)}, but keeps the scroll locked until the user
|
||||
* scrolls, or {@param v} loses focus or is detached.
|
||||
*/
|
||||
void lockScrollTo(View v);
|
||||
|
||||
/**
|
||||
* Request that the view does not dismiss for the current touch.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user