use of com.android.systemui.statusbar.ExpandableView in project android_frameworks_base by crdroidandroid.
the class HeadsUpTouchHelper method onInterceptTouchEvent.
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (!mTouchingHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return false;
}
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
mTrackingPointer = event.getPointerId(pointerIndex);
}
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mInitialTouchY = y;
mInitialTouchX = x;
setTrackingHeadsUp(false);
ExpandableView child = mStackScroller.getChildAtRawPosition(x, y);
mTouchingHeadsUpView = false;
if (child instanceof ExpandableNotificationRow) {
mPickedChild = (ExpandableNotificationRow) child;
mTouchingHeadsUpView = !mStackScroller.isExpanded() && mPickedChild.isHeadsUp() && mPickedChild.isPinned();
}
break;
case MotionEvent.ACTION_POINTER_UP:
final int upPointer = event.getPointerId(event.getActionIndex());
if (mTrackingPointer == upPointer) {
// gesture is ongoing, find a new pointer to track
final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
mTrackingPointer = event.getPointerId(newIndex);
mInitialTouchX = event.getX(newIndex);
mInitialTouchY = event.getY(newIndex);
}
break;
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
if (mTouchingHeadsUpView && Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)) {
setTrackingHeadsUp(true);
mCollapseSnoozes = h < 0;
mInitialTouchX = x;
mInitialTouchY = y;
int expandedHeight = mPickedChild.getActualHeight();
mPanel.setPanelScrimMinFraction((float) expandedHeight / mPanel.getMaxPanelHeight());
mPanel.startExpandMotion(x, y, true, /* startTracking */
expandedHeight);
// This call needs to be after the expansion start otherwise we will get a
// flicker of one frame as it's not expanded yet.
mHeadsUpManager.unpinAll();
mPanel.clearNotificationEffects();
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mPickedChild != null && mTouchingHeadsUpView) {
// We may swallow this click if the heads up just came in.
if (mHeadsUpManager.shouldSwallowClick(mPickedChild.getStatusBarNotification().getKey())) {
endMotion();
return true;
}
}
endMotion();
break;
}
return false;
}
use of com.android.systemui.statusbar.ExpandableView in project android_frameworks_base by crdroidandroid.
the class StackStateAnimator method startAnimationForEvents.
public void startAnimationForEvents(ArrayList<NotificationStackScrollLayout.AnimationEvent> mAnimationEvents, StackScrollState finalState, long additionalDelay) {
processAnimationEvents(mAnimationEvents, finalState);
int childCount = mHostLayout.getChildCount();
mAnimationFilter.applyCombination(mNewEvents);
mCurrentAdditionalDelay = additionalDelay;
mCurrentLength = NotificationStackScrollLayout.AnimationEvent.combineLength(mNewEvents);
mCurrentLastNotAddedIndex = findLastNotAddedIndex(finalState);
for (int i = 0; i < childCount; i++) {
final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
StackViewState viewState = finalState.getViewStateForView(child);
if (viewState == null || child.getVisibility() == View.GONE || applyWithoutAnimation(child, viewState, finalState)) {
continue;
}
startStackAnimations(child, viewState, finalState, i, -1);
}
if (!isRunning()) {
// no child has preformed any animation, lets finish
onAnimationFinished();
}
mHeadsUpAppearChildren.clear();
mHeadsUpDisappearChildren.clear();
mNewEvents.clear();
mNewAddChildren.clear();
}
use of com.android.systemui.statusbar.ExpandableView in project android_frameworks_base by crdroidandroid.
the class StackStateAnimator method processAnimationEvents.
/**
* Process the animationEvents for a new animation
*
* @param animationEvents the animation events for the animation to perform
* @param finalState the final state to animate to
*/
private void processAnimationEvents(ArrayList<NotificationStackScrollLayout.AnimationEvent> animationEvents, StackScrollState finalState) {
for (NotificationStackScrollLayout.AnimationEvent event : animationEvents) {
final ExpandableView changingView = (ExpandableView) event.changingView;
if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD) {
// This item is added, initialize it's properties.
StackViewState viewState = finalState.getViewStateForView(changingView);
if (viewState == null) {
// The position for this child was never generated, let's continue.
continue;
}
finalState.applyState(changingView, viewState);
mNewAddChildren.add(changingView);
} else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE) {
if (changingView.getVisibility() == View.GONE) {
removeFromOverlay(changingView);
continue;
}
// Find the amount to translate up. This is needed in order to understand the
// direction of the remove animation (either downwards or upwards)
StackViewState viewState = finalState.getViewStateForView(event.viewAfterChangingView);
int actualHeight = changingView.getActualHeight();
// upwards by default
float translationDirection = -1.0f;
if (viewState != null) {
// there was a view after this one, Approximate the distance the next child
// travelled
translationDirection = ((viewState.yTranslation - (changingView.getTranslationY() + actualHeight / 2.0f)) * 2 / actualHeight);
translationDirection = Math.max(Math.min(translationDirection, 1.0f), -1.0f);
}
changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR, translationDirection, new Runnable() {
@Override
public void run() {
// remove the temporary overlay
removeFromOverlay(changingView);
}
});
} else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
// A race condition can trigger the view to be added to the overlay even though
// it was fully swiped out. So let's remove it
mHostLayout.getOverlay().remove(changingView);
if (Math.abs(changingView.getTranslation()) == changingView.getWidth() && changingView.getTransientContainer() != null) {
changingView.getTransientContainer().removeTransientView(changingView);
}
} else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GROUP_EXPANSION_CHANGED) {
ExpandableNotificationRow row = (ExpandableNotificationRow) event.changingView;
row.prepareExpansionChanged(finalState);
} else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR) {
// This item is added, initialize it's properties.
StackViewState viewState = finalState.getViewStateForView(changingView);
mTmpState.copyFrom(viewState);
if (event.headsUpFromBottom) {
mTmpState.yTranslation = mHeadsUpAppearHeightBottom;
} else {
mTmpState.yTranslation = -mTmpState.height;
}
mHeadsUpAppearChildren.add(changingView);
finalState.applyState(changingView, mTmpState);
} else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR || event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
mHeadsUpDisappearChildren.add(changingView);
if (changingView.getParent() == null) {
// This notification was actually removed, so we need to add it to the overlay
mHostLayout.getOverlay().add(changingView);
mTmpState.initFrom(changingView);
mTmpState.yTranslation = -changingView.getActualHeight();
// We temporarily enable Y animations, the real filter will be combined
// afterwards anyway
mAnimationFilter.animateY = true;
startViewAnimations(changingView, mTmpState, event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK ? ANIMATION_DELAY_HEADS_UP : 0, ANIMATION_DURATION_HEADS_UP_DISAPPEAR);
mChildrenToClearFromOverlay.add(changingView);
}
}
mNewEvents.add(event);
}
}
use of com.android.systemui.statusbar.ExpandableView in project android_frameworks_base by crdroidandroid.
the class NotificationStackScrollLayout method updateViewShadows.
private void updateViewShadows() {
// Lefts first sort by Z difference
for (int i = 0; i < getChildCount(); i++) {
ExpandableView child = (ExpandableView) getChildAt(i);
if (child.getVisibility() != GONE) {
mTmpSortedChildren.add(child);
}
}
Collections.sort(mTmpSortedChildren, mViewPositionComparator);
// Now lets update the shadow for the views
ExpandableView previous = null;
for (int i = 0; i < mTmpSortedChildren.size(); i++) {
ExpandableView expandableView = mTmpSortedChildren.get(i);
float translationZ = expandableView.getTranslationZ();
float otherZ = previous == null ? translationZ : previous.getTranslationZ();
float diff = otherZ - translationZ;
if (diff <= 0.0f || diff >= FakeShadowView.SHADOW_SIBLING_TRESHOLD) {
// There is no fake shadow to be drawn
expandableView.setFakeShadowIntensity(0.0f, 0.0f, 0, 0);
} else {
float yLocation = previous.getTranslationY() + previous.getActualHeight() - expandableView.getTranslationY() - previous.getExtraBottomPadding();
expandableView.setFakeShadowIntensity(diff / FakeShadowView.SHADOW_SIBLING_TRESHOLD, previous.getOutlineAlpha(), (int) yLocation, previous.getOutlineTranslation());
}
previous = expandableView;
}
mTmpSortedChildren.clear();
}
use of com.android.systemui.statusbar.ExpandableView in project android_frameworks_base by crdroidandroid.
the class StackScrollAlgorithm method initAlgorithmState.
/**
* Initialize the algorithm state like updating the visible children.
*/
private void initAlgorithmState(StackScrollState resultState, StackScrollAlgorithmState state, AmbientState ambientState) {
state.itemsInBottomStack = 0.0f;
state.partialInBottom = 0.0f;
float bottomOverScroll = ambientState.getOverScrollAmount(false);
int scrollY = ambientState.getScrollY();
// Due to the overScroller, the stackscroller can have negative scroll state. This is
// already accounted for by the top padding and doesn't need an additional adaption
scrollY = Math.max(0, scrollY);
state.scrollY = (int) (scrollY + bottomOverScroll);
//now init the visible children and update paddings
ViewGroup hostView = resultState.getHostView();
int childCount = hostView.getChildCount();
state.visibleChildren.clear();
state.visibleChildren.ensureCapacity(childCount);
state.increasedPaddingMap.clear();
int notGoneIndex = 0;
ExpandableView lastView = null;
for (int i = 0; i < childCount; i++) {
ExpandableView v = (ExpandableView) hostView.getChildAt(i);
if (v.getVisibility() != View.GONE) {
notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v);
float increasedPadding = v.getIncreasedPaddingAmount();
if (increasedPadding != 0.0f) {
state.increasedPaddingMap.put(v, increasedPadding);
if (lastView != null) {
Float prevValue = state.increasedPaddingMap.get(lastView);
float newValue = prevValue != null ? Math.max(prevValue, increasedPadding) : increasedPadding;
state.increasedPaddingMap.put(lastView, newValue);
}
}
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
// handle the notgoneIndex for the children as well
List<ExpandableNotificationRow> children = row.getNotificationChildren();
if (row.isSummaryWithChildren() && children != null) {
for (ExpandableNotificationRow childRow : children) {
if (childRow.getVisibility() != View.GONE) {
StackViewState childState = resultState.getViewStateForView(childRow);
childState.notGoneIndex = notGoneIndex;
notGoneIndex++;
}
}
}
}
lastView = v;
}
}
}
Aggregations