Methods Summary |
---|
void | animateChallengeTo(int y, int velocity)Animate the bottom edge of the challenge view to the given position.
if (mChallengeView == null) {
// Nothing to do.
return;
}
cancelTransitionsInProgress();
mChallengeInteractiveInternal = false;
enableHardwareLayerForChallengeView();
final int sy = mChallengeView.getBottom();
final int dy = y - sy;
if (dy == 0) {
completeChallengeScroll();
return;
}
setScrollState(SCROLL_STATE_SETTLING);
final int childHeight = mChallengeView.getHeight();
final int halfHeight = childHeight / 2;
final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dy) / childHeight);
final float distance = halfHeight + halfHeight *
distanceInfluenceForSnapDuration(distanceRatio);
int duration = 0;
velocity = Math.abs(velocity);
if (velocity > 0) {
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
} else {
final float childDelta = (float) Math.abs(dy) / childHeight;
duration = (int) ((childDelta + 1) * 100);
}
duration = Math.min(duration, MAX_SETTLE_DURATION);
mScroller.startScroll(0, sy, 0, dy, duration);
postInvalidateOnAnimation();
|
void | animateHandle(boolean visible)
if (mHandleAnimation != null) {
mHandleAnimation.cancel();
mHandleAnimation = null;
}
final float targetAlpha = visible ? 1.f : 0.f;
if (targetAlpha == mHandleAlpha) {
return;
}
mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, targetAlpha);
mHandleAnimation.setInterpolator(sHandleFadeInterpolator);
mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION);
mHandleAnimation.start();
|
private void | cancelTransitionsInProgress()
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
completeChallengeScroll();
}
if (mFader != null) {
mFader.cancel();
}
|
protected boolean | checkLayoutParams(ViewGroup.LayoutParams p)
return p instanceof LayoutParams;
|
void | completeChallengeScroll()
setChallengeShowing(mChallengeShowingTargetState);
mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
setScrollState(SCROLL_STATE_IDLE);
mChallengeInteractiveInternal = true;
mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
|
public void | computeScroll()
super.computeScroll();
if (!mScroller.isFinished()) {
if (mChallengeView == null) {
// Can't scroll if the view is missing.
Log.e(TAG, "Challenge view missing in computeScroll");
mScroller.abortAnimation();
return;
}
mScroller.computeScrollOffset();
moveChallengeTo(mScroller.getCurrY());
if (mScroller.isFinished()) {
post(mEndScrollRunnable);
}
}
|
private boolean | crossedDragHandle(float x, float y, float initialY)
final int challengeTop = mChallengeView.getTop();
final boolean horizOk = x >= 0 && x < getWidth();
final boolean vertOk;
if (mChallengeShowing) {
vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
y > challengeTop + getDragHandleSizeBelow();
} else {
vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
y < challengeTop - getDragHandleSizeAbove();
}
return horizOk && vertOk;
|
public boolean | dispatchTouchEvent(android.view.MotionEvent ev)The lifecycle of touch events is subtle and it's very easy to do something
that will cause bugs that will be nasty to track when overriding this method.
Normally one should always override onInterceptTouchEvent instead.
To put it another way, don't try this at home.
final int action = ev.getActionMasked();
boolean handled = false;
if (action == MotionEvent.ACTION_DOWN) {
// Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
mEdgeCaptured = false;
}
if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
// Normally we would need to do a lot of extra stuff here.
// We can only get away with this because we haven't padded in
// the widget pager or otherwise transformed it during layout.
// We also don't support things like splitting MotionEvents.
// We set handled to captured even if dispatch is returning false here so that
// we don't send a different view a busted or incomplete event stream.
handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
}
if (!handled && !mEdgeCaptured) {
handled = super.dispatchTouchEvent(ev);
}
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
mEdgeCaptured = false;
}
return handled;
|
float | distanceInfluenceForSnapDuration(float f)
f -= 0.5f; // center the values about 0.
f *= 0.3f * Math.PI / 2.0f;
return (float) Math.sin(f);
|
public void | draw(android.graphics.Canvas c)
super.draw(c);
if (DEBUG) {
final Paint debugPaint = new Paint();
debugPaint.setColor(0x40FF00CC);
// show the isInDragHandle() rect
c.drawRect(mDragHandleEdgeSlop,
mChallengeView.getTop() - getDragHandleSizeAbove(),
getWidth() - mDragHandleEdgeSlop,
mChallengeView.getTop() + getDragHandleSizeBelow(),
debugPaint);
}
|
private void | enableHardwareLayerForChallengeView()
if (mChallengeView.isHardwareAccelerated()) {
mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
}
|
public void | fadeChallenge(boolean show)
if (mChallengeView != null) {
cancelTransitionsInProgress();
float alpha = show ? 1f : 0f;
int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION;
mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha);
mFader.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
onFadeStart(show);
}
@Override
public void onAnimationEnd(Animator animation) {
onFadeEnd(show);
}
});
mFader.setDuration(duration);
mFader.start();
}
|
public void | fadeInChallenge()
fadeChallenge(true);
|
public void | fadeOutChallenge()
fadeChallenge(false);
|
protected ViewGroup.LayoutParams | generateDefaultLayoutParams()
return new LayoutParams();
|
public ViewGroup.LayoutParams | generateLayoutParams(android.util.AttributeSet attrs)
return new LayoutParams(getContext(), attrs);
|
protected ViewGroup.LayoutParams | generateLayoutParams(ViewGroup.LayoutParams p)
return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
new LayoutParams(p);
|
public int | getBouncerAnimationDuration()
return HANDLE_ANIMATE_DURATION;
|
private float | getChallengeAlpha()
float x = mChallengeOffset - 1;
return x * x * x + 1.f;
|
private int | getChallengeBottom()The bottom edge of mChallengeView; essentially, where the sliding challenge 'is'.
if (mChallengeView == null) return 0;
return mChallengeView.getBottom();
|
private int | getChallengeMargin(boolean expanded)
return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
|
private int | getDragHandleSizeAbove()We only want to add additional vertical space to the drag handle when the panel is fully
closed.
return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
|
private int | getDragHandleSizeBelow()
return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
|
private int | getLayoutBottom()The bottom edge of this SlidingChallengeLayout's coordinate system; will coincide with
the bottom edge of mChallengeView when the challenge is fully opened.
final int bottomMargin = (mChallengeView == null)
? 0
: ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin
- mInsets.bottom;
return layoutBottom;
|
private int | getMaxChallengeBottom()
if (mChallengeView == null) return 0;
final int layoutBottom = getLayoutBottom();
final int challengeHeight = mChallengeView.getMeasuredHeight();
return (layoutBottom + challengeHeight - mChallengeBottomBound);
|
public int | getMaxChallengeTop()
if (mChallengeView == null) return 0;
final int layoutBottom = getLayoutBottom();
final int challengeHeight = mChallengeView.getMeasuredHeight();
return layoutBottom - challengeHeight - mInsets.top;
|
private int | getMinChallengeBottom()
return getLayoutBottom();
|
public void | hideBouncer()
if (!mIsBouncing) return;
setSystemUiVisibility(getSystemUiVisibility() & ~STATUS_BAR_DISABLE_SEARCH);
if (!mWasChallengeShowing) showChallenge(false);
mIsBouncing = false;
if (mScrimView != null) {
Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
anim.setDuration(HANDLE_ANIMATE_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mScrimView.setVisibility(GONE);
}
});
anim.start();
}
if (mChallengeView != null) {
mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
}
if (mBouncerListener != null) {
mBouncerListener.onBouncerStateChanged(false);
}
|
public boolean | isBouncing()
return mIsBouncing;
|
private boolean | isChallengeInteractionBlocked()
return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal;
|
public boolean | isChallengeOverlapping()
return mChallengeShowing;
|
public boolean | isChallengeShowing()
return mChallengeShowing;
|
private boolean | isEdgeSwipeBeginEvent(android.view.MotionEvent ev)
if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
return false;
}
final float x = ev.getX();
return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
|
private boolean | isInChallengeView(float x, float y)
return isPointInView(x, y, mChallengeView);
|
private boolean | isInDragHandle(float x, float y)
return isPointInView(x, y, mExpandChallengeView);
|
private boolean | isPointInView(float x, float y, android.view.View view)
if (view == null) {
return false;
}
return x >= view.getLeft() && y >= view.getTop()
&& x < view.getRight() && y < view.getBottom();
|
private int | makeChildMeasureSpec(int maxSize, int childDimen)
final int mode;
final int size;
switch (childDimen) {
case LayoutParams.WRAP_CONTENT:
mode = MeasureSpec.AT_MOST;
size = maxSize;
break;
case LayoutParams.MATCH_PARENT:
mode = MeasureSpec.EXACTLY;
size = maxSize;
break;
default:
mode = MeasureSpec.EXACTLY;
size = Math.min(maxSize, childDimen);
break;
}
return MeasureSpec.makeMeasureSpec(size, mode);
|
private boolean | moveChallengeTo(int bottom)Move the bottom edge of mChallengeView to a new position and notify the listener
if it represents a change in position. Changes made through this method will
be stable across layout passes. If this method is called before first layout of
this SlidingChallengeLayout it will have no effect.
if (mChallengeView == null || !mHasLayout) {
return false;
}
final int layoutBottom = getLayoutBottom();
final int challengeHeight = mChallengeView.getHeight();
bottom = Math.max(getMinChallengeBottom(),
Math.min(bottom, getMaxChallengeBottom()));
float offset = 1.f - (float) (bottom - layoutBottom) /
(challengeHeight - mChallengeBottomBound);
mChallengeOffset = offset;
if (offset > 0 && !mChallengeShowing) {
setChallengeShowing(true);
}
mChallengeView.layout(mChallengeView.getLeft(),
bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);
mChallengeView.setAlpha(getChallengeAlpha());
if (mScrollListener != null) {
mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
}
postInvalidateOnAnimation();
return true;
|
public void | onAttachedToWindow()
super.onAttachedToWindow();
mHasLayout = false;
|
public void | onDetachedFromWindow()
super.onDetachedFromWindow();
removeCallbacks(mEndScrollRunnable);
mHasLayout = false;
|
private void | onFadeEnd(boolean show)
mChallengeInteractiveInternal = true;
setChallengeShowing(show);
if (!show) {
moveChallengeTo(getMaxChallengeBottom());
}
mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
mFader = null;
setScrollState(SCROLL_STATE_IDLE);
|
private void | onFadeStart(boolean show)
mChallengeInteractiveInternal = false;
enableHardwareLayerForChallengeView();
if (show) {
moveChallengeTo(getMinChallengeBottom());
}
setScrollState(SCROLL_STATE_FADING);
|
public boolean | onInterceptTouchEvent(android.view.MotionEvent ev)
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
mGestureStartX = ev.getX();
mGestureStartY = ev.getY();
mBlockDrag = false;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
resetTouch();
break;
case MotionEvent.ACTION_MOVE:
final int count = ev.getPointerCount();
for (int i = 0; i < count; i++) {
final float x = ev.getX(i);
final float y = ev.getY(i);
if (!mIsBouncing && mActivePointerId == INVALID_POINTER
&& (crossedDragHandle(x, y, mGestureStartY)
&& shouldEnableChallengeDragging()
|| (isInChallengeView(x, y) &&
mScrollState == SCROLL_STATE_SETTLING))) {
mActivePointerId = ev.getPointerId(i);
mGestureStartX = x;
mGestureStartY = y;
mGestureStartChallengeBottom = getChallengeBottom();
mDragging = true;
enableHardwareLayerForChallengeView();
} else if (mChallengeShowing && isInChallengeView(x, y)
&& shouldEnableChallengeDragging()) {
mBlockDrag = true;
}
}
break;
}
if (mBlockDrag || isChallengeInteractionBlocked()) {
mActivePointerId = INVALID_POINTER;
mDragging = false;
}
return mDragging;
|
protected void | onLayout(boolean changed, int l, int t, int r, int b)
final int paddingLeft = getPaddingLeft();
final int paddingTop = getPaddingTop();
final int paddingRight = getPaddingRight();
final int paddingBottom = getPaddingBottom();
final int width = r - l;
final int height = b - t;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) continue;
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
// Challenge views pin to the bottom, offset by a portion of their height,
// and center horizontally.
final int center = (paddingLeft + width - paddingRight) / 2;
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
final int left = center - childWidth / 2;
final int layoutBottom = height - paddingBottom - lp.bottomMargin - mInsets.bottom;
// We use the top of the challenge view to position the handle, so
// we never want less than the handle size showing at the bottom.
final int bottom = layoutBottom + (int) ((childHeight - mChallengeBottomBound)
* (1 - mChallengeOffset));
child.setAlpha(getChallengeAlpha());
child.layout(left, bottom - childHeight, left + childWidth, bottom);
} else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
final int center = (paddingLeft + width - paddingRight) / 2;
final int left = center - child.getMeasuredWidth() / 2;
final int right = left + child.getMeasuredWidth();
final int bottom = height - paddingBottom - lp.bottomMargin - mInsets.bottom;
final int top = bottom - child.getMeasuredHeight();
child.layout(left, top, right, bottom);
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
// Scrim views use the entire area, including padding & insets
child.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
} else {
// Non-challenge views lay out from the upper left, layered.
child.layout(paddingLeft + lp.leftMargin,
paddingTop + lp.topMargin + mInsets.top,
paddingLeft + child.getMeasuredWidth(),
paddingTop + child.getMeasuredHeight() + mInsets.top);
}
}
if (!mHasLayout) {
mHasLayout = true;
}
|
protected void | onMeasure(int widthSpec, int heightSpec)
if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
throw new IllegalArgumentException(
"SlidingChallengeLayout must be measured with an exact size");
}
final int width = MeasureSpec.getSize(widthSpec);
final int height = MeasureSpec.getSize(heightSpec);
setMeasuredDimension(width, height);
final int insetHeight = height - mInsets.top - mInsets.bottom;
final int insetHeightSpec = MeasureSpec.makeMeasureSpec(insetHeight, MeasureSpec.EXACTLY);
// Find one and only one challenge view.
final View oldChallengeView = mChallengeView;
final View oldExpandChallengeView = mChallengeView;
mChallengeView = null;
mExpandChallengeView = null;
final int count = getChildCount();
// First iteration through the children finds special children and sets any associated
// state.
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
if (mChallengeView != null) {
throw new IllegalStateException(
"There may only be one child with layout_isChallenge=\"true\"");
}
if (!(child instanceof KeyguardSecurityContainer)) {
throw new IllegalArgumentException(
"Challenge must be a KeyguardSecurityContainer");
}
mChallengeView = (KeyguardSecurityContainer) child;
if (mChallengeView != oldChallengeView) {
mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
}
// We're going to play silly games with the frame's background drawable later.
if (!mHasLayout) {
// Set up the margin correctly based on our content for the first run.
mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
}
} else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
if (mExpandChallengeView != null) {
throw new IllegalStateException(
"There may only be one child with layout_childType"
+ "=\"expandChallengeHandle\"");
}
mExpandChallengeView = child;
if (mExpandChallengeView != oldExpandChallengeView) {
mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
}
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
setScrimView(child);
} else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
mWidgetsView = child;
}
}
// We want to measure the challenge view first, since the KeyguardWidgetPager
// needs to do things its measure pass that are dependent on the challenge view
// having been measured.
if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
// This one's a little funny. If the IME is present - reported in the form
// of insets on the root view - we only give the challenge the space it would
// have had if the IME wasn't there in order to keep the rest of the layout stable.
// We base this on the layout_maxHeight on the challenge view. If it comes out
// negative or zero, either we didn't have a maxHeight or we're totally out of space,
// so give up and measure as if this rule weren't there.
int challengeHeightSpec = insetHeightSpec;
final View root = getRootView();
if (root != null) {
final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
final int windowHeight = mDisplayMetrics.heightPixels
- root.getPaddingTop() - mInsets.top;
final int diff = windowHeight - insetHeight;
final int maxChallengeHeight = lp.maxHeight - diff;
if (maxChallengeHeight > 0) {
challengeHeightSpec = makeChildMeasureSpec(maxChallengeHeight, lp.height);
}
}
measureChildWithMargins(mChallengeView, widthSpec, 0, challengeHeightSpec, 0);
}
// Measure the rest of the children
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// Don't measure the challenge view twice!
if (child == mChallengeView) continue;
// Measure children. Widget frame measures special, so that we can ignore
// insets for the IME.
int parentWidthSpec = widthSpec, parentHeightSpec = insetHeightSpec;
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
final View root = getRootView();
if (root != null) {
// This calculation is super dodgy and relies on several assumptions.
// Specifically that the root of the window will be padded in for insets
// and that the window is LAYOUT_IN_SCREEN.
final int windowWidth = mDisplayMetrics.widthPixels;
final int windowHeight = mDisplayMetrics.heightPixels
- root.getPaddingTop() - mInsets.top;
parentWidthSpec = MeasureSpec.makeMeasureSpec(
windowWidth, MeasureSpec.EXACTLY);
parentHeightSpec = MeasureSpec.makeMeasureSpec(
windowHeight, MeasureSpec.EXACTLY);
}
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
// Allow scrim views to extend into the insets
parentWidthSpec = widthSpec;
parentHeightSpec = heightSpec;
}
measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
}
|
protected boolean | onRequestFocusInDescendants(int direction, android.graphics.Rect previouslyFocusedRect)
// Focus security fileds before widgets.
if (mChallengeView != null &&
mChallengeView.requestFocus(direction, previouslyFocusedRect)) {
return true;
}
return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
|
public boolean | onTouchEvent(android.view.MotionEvent ev)
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
mBlockDrag = false;
mGestureStartX = ev.getX();
mGestureStartY = ev.getY();
break;
case MotionEvent.ACTION_CANCEL:
if (mDragging && !isChallengeInteractionBlocked()) {
showChallenge(0);
}
resetTouch();
break;
case MotionEvent.ACTION_POINTER_UP:
if (mActivePointerId != ev.getPointerId(ev.getActionIndex())) {
break;
}
case MotionEvent.ACTION_UP:
if (mDragging && !isChallengeInteractionBlocked()) {
mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
}
resetTouch();
break;
case MotionEvent.ACTION_MOVE:
if (!mDragging && !mBlockDrag && !mIsBouncing) {
final int count = ev.getPointerCount();
for (int i = 0; i < count; i++) {
final float x = ev.getX(i);
final float y = ev.getY(i);
if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
(isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
&& mActivePointerId == INVALID_POINTER
&& !isChallengeInteractionBlocked()) {
mGestureStartX = x;
mGestureStartY = y;
mActivePointerId = ev.getPointerId(i);
mGestureStartChallengeBottom = getChallengeBottom();
mDragging = true;
enableHardwareLayerForChallengeView();
break;
}
}
}
// Not an else; this can be set above.
if (mDragging) {
// No-op if already in this state, but set it here in case we arrived
// at this point from either intercept or the above.
setScrollState(SCROLL_STATE_DRAGGING);
final int index = ev.findPointerIndex(mActivePointerId);
if (index < 0) {
// Oops, bogus state. We lost some touch events somewhere.
// Just drop it with no velocity and let things settle.
resetTouch();
showChallenge(0);
return true;
}
final float y = ev.getY(index);
final float pos = Math.min(y - mGestureStartY,
getLayoutBottom() - mChallengeBottomBound);
moveChallengeTo(mGestureStartChallengeBottom + (int) pos);
}
break;
}
return true;
|
public void | requestChildFocus(android.view.View child, android.view.View focused)
if (mIsBouncing && child != mChallengeView) {
// Clear out of the bouncer if the user tries to move focus outside of
// the security challenge view.
hideBouncer();
}
super.requestChildFocus(child, focused);
|
public void | requestDisallowInterceptTouchEvent(boolean allowIntercept)
// We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
// If there are one or more pointers in the challenge view before we take over
// touch events, onInterceptTouchEvent will set mBlockDrag.
|
private void | resetTouch()
mVelocityTracker.recycle();
mVelocityTracker = null;
mActivePointerId = INVALID_POINTER;
mDragging = mBlockDrag = false;
|
private void | sendInitialListenerUpdates()
if (mScrollListener != null) {
int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
mScrollListener.onScrollStateChanged(mScrollState);
}
|
public void | setChallengeInteractive(boolean interactive)
mChallengeInteractiveExternal = interactive;
if (mExpandChallengeView != null) {
mExpandChallengeView.setEnabled(interactive);
}
|
private void | setChallengeShowing(boolean showChallenge)
if (mChallengeShowing == showChallenge) {
return;
}
mChallengeShowing = showChallenge;
if (mExpandChallengeView == null || mChallengeView == null) {
// These might not be here yet if we haven't been through layout.
// If we haven't, the first layout pass will set everything up correctly
// based on mChallengeShowing as set above.
return;
}
if (mChallengeShowing) {
mExpandChallengeView.setVisibility(View.INVISIBLE);
mChallengeView.setVisibility(View.VISIBLE);
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
mChallengeView.requestAccessibilityFocus();
mChallengeView.announceForAccessibility(mContext.getString(
R.string.keyguard_accessibility_unlock_area_expanded));
}
} else {
mExpandChallengeView.setVisibility(View.VISIBLE);
mChallengeView.setVisibility(View.INVISIBLE);
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
mExpandChallengeView.requestAccessibilityFocus();
mChallengeView.announceForAccessibility(mContext.getString(
R.string.keyguard_accessibility_unlock_area_collapsed));
}
}
|
public void | setEnableChallengeDragging(boolean enabled)
mEnableChallengeDragging = enabled;
|
public void | setHandleAlpha(float alpha)
if (mExpandChallengeView != null) {
mExpandChallengeView.setAlpha(alpha);
}
|
public void | setInsets(android.graphics.Rect insets)
mInsets.set(insets);
|
public void | setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener)
mBouncerListener = listener;
|
public void | setOnChallengeScrolledListener(com.android.keyguard.SlidingChallengeLayout$OnChallengeScrolledListener listener)
mScrollListener = listener;
if (mHasLayout) {
sendInitialListenerUpdates();
}
|
void | setScrimView(android.view.View scrim)
if (mScrimView != null) {
mScrimView.setOnClickListener(null);
}
mScrimView = scrim;
if (mScrimView != null) {
mScrimView.setVisibility(mIsBouncing ? VISIBLE : GONE);
mScrimView.setFocusable(true);
mScrimView.setOnClickListener(mScrimClickListener);
}
|
void | setScrollState(int state)
if (mScrollState != state) {
mScrollState = state;
animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
if (mScrollListener != null) {
mScrollListener.onScrollStateChanged(state);
}
}
|
private boolean | shouldEnableChallengeDragging()
return mEnableChallengeDragging || !mChallengeShowing;
|
public void | showBouncer()
if (mIsBouncing) return;
setSystemUiVisibility(getSystemUiVisibility() | STATUS_BAR_DISABLE_SEARCH);
mWasChallengeShowing = mChallengeShowing;
mIsBouncing = true;
showChallenge(true);
if (mScrimView != null) {
Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
anim.setDuration(HANDLE_ANIMATE_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mScrimView.setVisibility(VISIBLE);
}
});
anim.start();
}
if (mChallengeView != null) {
mChallengeView.showBouncer(HANDLE_ANIMATE_DURATION);
}
if (mBouncerListener != null) {
mBouncerListener.onBouncerStateChanged(true);
}
|
public void | showChallenge(boolean show)Show or hide the challenge view, animating it if necessary.
showChallenge(show, 0);
if (!show) {
// Block any drags in progress so that callers can use this to disable dragging
// for other touch interactions.
mBlockDrag = true;
}
|
private void | showChallenge(int velocity)
boolean show = false;
if (Math.abs(velocity) > mMinVelocity) {
show = velocity < 0;
} else {
show = mChallengeOffset >= 0.5f;
}
showChallenge(show, velocity);
|
private void | showChallenge(boolean show, int velocity)
if (mChallengeView == null) {
setChallengeShowing(false);
return;
}
if (mHasLayout) {
mChallengeShowingTargetState = show;
final int layoutBottom = getLayoutBottom();
animateChallengeTo(show ? layoutBottom :
layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
}
|