Refactored clipping util to be used in core
We need the possibility to disable clipping up a view hierarchy also in core, so I'm moving it and refactoring it. Test: expand, observe normal clipping Bug: 63708826 Change-Id: I157395be8f2b7ac75afc0a3967cb0f2068a02fb6
This commit is contained in:
108
core/java/com/android/internal/widget/ViewClippingUtil.java
Normal file
108
core/java/com/android/internal/widget/ViewClippingUtil.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.internal.widget;
|
||||
|
||||
import android.util.ArraySet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
/**
|
||||
* A utility class that allows to clip views and their parents to allow for better transitions
|
||||
*/
|
||||
public class ViewClippingUtil {
|
||||
private static final int CLIP_CLIPPING_SET = R.id.clip_children_set_tag;
|
||||
private static final int CLIP_CHILDREN_TAG = R.id.clip_children_tag;
|
||||
private static final int CLIP_TO_PADDING = R.id.clip_to_padding_tag;
|
||||
|
||||
public static void setClippingDeactivated(final View transformedView, boolean deactivated,
|
||||
ClippingParameters clippingParameters) {
|
||||
if (!deactivated && !clippingParameters.isClippingEnablingAllowed(transformedView)) {
|
||||
return;
|
||||
}
|
||||
if (!(transformedView.getParent() instanceof ViewGroup)) {
|
||||
return;
|
||||
}
|
||||
ViewGroup parent = (ViewGroup) transformedView.getParent();
|
||||
while (true) {
|
||||
if (!deactivated && !clippingParameters.isClippingEnablingAllowed(transformedView)) {
|
||||
return;
|
||||
}
|
||||
ArraySet<View> clipSet = (ArraySet<View>) parent.getTag(CLIP_CLIPPING_SET);
|
||||
if (clipSet == null) {
|
||||
clipSet = new ArraySet<>();
|
||||
parent.setTagInternal(CLIP_CLIPPING_SET, clipSet);
|
||||
}
|
||||
Boolean clipChildren = (Boolean) parent.getTag(CLIP_CHILDREN_TAG);
|
||||
if (clipChildren == null) {
|
||||
clipChildren = parent.getClipChildren();
|
||||
parent.setTagInternal(CLIP_CHILDREN_TAG, clipChildren);
|
||||
}
|
||||
Boolean clipToPadding = (Boolean) parent.getTag(CLIP_TO_PADDING);
|
||||
if (clipToPadding == null) {
|
||||
clipToPadding = parent.getClipToPadding();
|
||||
parent.setTagInternal(CLIP_TO_PADDING, clipToPadding);
|
||||
}
|
||||
if (!deactivated) {
|
||||
clipSet.remove(transformedView);
|
||||
if (clipSet.isEmpty()) {
|
||||
parent.setClipChildren(clipChildren);
|
||||
parent.setClipToPadding(clipToPadding);
|
||||
parent.setTagInternal(CLIP_CLIPPING_SET, null);
|
||||
clippingParameters.onClippingStateChanged(parent, true);
|
||||
}
|
||||
} else {
|
||||
clipSet.add(transformedView);
|
||||
parent.setClipChildren(false);
|
||||
parent.setClipToPadding(false);
|
||||
clippingParameters.onClippingStateChanged(parent, false);
|
||||
}
|
||||
if (clippingParameters.shouldFinish(parent)) {
|
||||
return;
|
||||
}
|
||||
final ViewParent viewParent = parent.getParent();
|
||||
if (viewParent instanceof ViewGroup) {
|
||||
parent = (ViewGroup) viewParent;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface ClippingParameters {
|
||||
/**
|
||||
* Should we stop clipping at this view? If true is returned, {@param view} is the last view
|
||||
* where clipping is activated / deactivated.
|
||||
*/
|
||||
boolean shouldFinish(View view);
|
||||
|
||||
/**
|
||||
* Is it allowed to enable clipping on this view.
|
||||
*/
|
||||
default boolean isClippingEnablingAllowed(View view) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A method that is called whenever the view starts clipping again / stops clipping to the
|
||||
* children and padding.
|
||||
*/
|
||||
default void onClippingStateChanged(View view, boolean isClipping) {};
|
||||
}
|
||||
}
|
||||
@@ -139,6 +139,15 @@
|
||||
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_MOVE_WINDOW}. -->
|
||||
<item type="id" name="accessibilityActionMoveWindow" />
|
||||
|
||||
<!-- A tag used to save the clip children in a tag -->
|
||||
<item type="id" name="clip_children_tag" />
|
||||
|
||||
<!-- A tag used to save the set of deactivated children that clip -->
|
||||
<item type="id" name="clip_children_set_tag" />
|
||||
|
||||
<!-- A tag used to save the clip to padding in a tag -->
|
||||
<item type="id" name="clip_to_padding_tag" />
|
||||
|
||||
<!-- Action used to manually trigger an autofill request -->
|
||||
<item type="id" name="autofill" />
|
||||
|
||||
|
||||
@@ -3111,6 +3111,9 @@
|
||||
<java-symbol type="id" name="message_name" />
|
||||
<java-symbol type="id" name="message_icon" />
|
||||
<java-symbol type="id" name="group_message_container" />
|
||||
<java-symbol type="id" name="clip_children_set_tag" />
|
||||
<java-symbol type="id" name="clip_to_padding_tag" />
|
||||
<java-symbol type="id" name="clip_children_tag" />
|
||||
<java-symbol type="drawable" name="ic_reply_notification_large" />
|
||||
<java-symbol type="dimen" name="messaging_avatar_size" />
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@
|
||||
|
||||
<!-- For notification icons for which targetSdk < L, this caches whether the icon is grayscale -->
|
||||
<item type="id" name="icon_is_grayscale" />
|
||||
<item type="id" name="clip_children_tag" />
|
||||
<item type="id" name="clip_children_set_tag" />
|
||||
<item type="id" name="clip_to_padding_tag" />
|
||||
<item type="id" name="image_icon_tag" />
|
||||
<item type="id" name="contains_transformed_view" />
|
||||
<item type="id" name="is_clicked_heads_up_tag" />
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.widget.ViewClippingUtil;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||
@@ -43,14 +44,34 @@ public class TransformState {
|
||||
public static final int TRANSFORM_ALL = TRANSFORM_X | TRANSFORM_Y;
|
||||
|
||||
private static final float UNDEFINED = -1f;
|
||||
private static final int CLIP_CLIPPING_SET = R.id.clip_children_set_tag;
|
||||
private static final int CLIP_CHILDREN_TAG = R.id.clip_children_tag;
|
||||
private static final int CLIP_TO_PADDING = R.id.clip_to_padding_tag;
|
||||
private static final int TRANSFORMATION_START_X = R.id.transformation_start_x_tag;
|
||||
private static final int TRANSFORMATION_START_Y = R.id.transformation_start_y_tag;
|
||||
private static final int TRANSFORMATION_START_SCLALE_X = R.id.transformation_start_scale_x_tag;
|
||||
private static final int TRANSFORMATION_START_SCLALE_Y = R.id.transformation_start_scale_y_tag;
|
||||
private static Pools.SimplePool<TransformState> sInstancePool = new Pools.SimplePool<>(40);
|
||||
private static ViewClippingUtil.ClippingParameters CLIPPING_PARAMETERS
|
||||
= new ViewClippingUtil.ClippingParameters() {
|
||||
@Override
|
||||
public boolean shouldFinish(View view) {
|
||||
if (view instanceof ExpandableNotificationRow) {
|
||||
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
|
||||
return !row.isChildInGroup();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClippingStateChanged(View view, boolean isClipping) {
|
||||
if (view instanceof ExpandableNotificationRow) {
|
||||
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
|
||||
if (isClipping) {
|
||||
row.setClipToActualHeight(true);
|
||||
} else if (row.isChildInGroup()) {
|
||||
row.setClipToActualHeight(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected View mTransformedView;
|
||||
private int[] mOwnPosition = new int[2];
|
||||
@@ -357,59 +378,8 @@ public class TransformState {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setClippingDeactivated(final View transformedView, boolean deactivated) {
|
||||
if (!(transformedView.getParent() instanceof ViewGroup)) {
|
||||
return;
|
||||
}
|
||||
ViewGroup view = (ViewGroup) transformedView.getParent();
|
||||
while (true) {
|
||||
ArraySet<View> clipSet = (ArraySet<View>) view.getTag(CLIP_CLIPPING_SET);
|
||||
if (clipSet == null) {
|
||||
clipSet = new ArraySet<>();
|
||||
view.setTag(CLIP_CLIPPING_SET, clipSet);
|
||||
}
|
||||
Boolean clipChildren = (Boolean) view.getTag(CLIP_CHILDREN_TAG);
|
||||
if (clipChildren == null) {
|
||||
clipChildren = view.getClipChildren();
|
||||
view.setTag(CLIP_CHILDREN_TAG, clipChildren);
|
||||
}
|
||||
Boolean clipToPadding = (Boolean) view.getTag(CLIP_TO_PADDING);
|
||||
if (clipToPadding == null) {
|
||||
clipToPadding = view.getClipToPadding();
|
||||
view.setTag(CLIP_TO_PADDING, clipToPadding);
|
||||
}
|
||||
ExpandableNotificationRow row = view instanceof ExpandableNotificationRow
|
||||
? (ExpandableNotificationRow) view
|
||||
: null;
|
||||
if (!deactivated) {
|
||||
clipSet.remove(transformedView);
|
||||
if (clipSet.isEmpty()) {
|
||||
view.setClipChildren(clipChildren);
|
||||
view.setClipToPadding(clipToPadding);
|
||||
view.setTag(CLIP_CLIPPING_SET, null);
|
||||
if (row != null) {
|
||||
row.setClipToActualHeight(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clipSet.add(transformedView);
|
||||
view.setClipChildren(false);
|
||||
view.setClipToPadding(false);
|
||||
if (row != null && row.isChildInGroup()) {
|
||||
// We still want to clip to the parent's height
|
||||
row.setClipToActualHeight(false);
|
||||
}
|
||||
}
|
||||
if (row != null && !row.isChildInGroup()) {
|
||||
return;
|
||||
}
|
||||
final ViewParent parent = view.getParent();
|
||||
if (parent instanceof ViewGroup) {
|
||||
view = (ViewGroup) parent;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
protected void setClippingDeactivated(final View transformedView, boolean deactivated) {
|
||||
ViewClippingUtil.setClippingDeactivated(transformedView, deactivated, CLIPPING_PARAMETERS);
|
||||
}
|
||||
|
||||
public int[] getLaidOutLocationOnScreen() {
|
||||
|
||||
Reference in New Issue
Block a user