am a073e570: Fix 6398209: General animation improvements for swipe to search
* commit 'a073e570789e5b49e8339af44516444b13db4428': Fix 6398209: General animation improvements for swipe to search
This commit is contained in:
@@ -19,6 +19,7 @@ package com.android.internal.widget.multiwaveview;
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
@@ -27,6 +28,7 @@ import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Vibrator;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
@@ -52,10 +54,11 @@ public class MultiWaveView extends View {
|
||||
|
||||
// Wave state machine
|
||||
private static final int STATE_IDLE = 0;
|
||||
private static final int STATE_FIRST_TOUCH = 1;
|
||||
private static final int STATE_TRACKING = 2;
|
||||
private static final int STATE_SNAP = 3;
|
||||
private static final int STATE_FINISH = 4;
|
||||
private static final int STATE_START = 1;
|
||||
private static final int STATE_FIRST_TOUCH = 2;
|
||||
private static final int STATE_TRACKING = 3;
|
||||
private static final int STATE_SNAP = 4;
|
||||
private static final int STATE_FINISH = 5;
|
||||
|
||||
// Animation properties.
|
||||
private static final float SNAP_MARGIN_DEFAULT = 20.0f; // distance to ring before we snap to it
|
||||
@@ -74,17 +77,18 @@ public class MultiWaveView extends View {
|
||||
private static final int CHEVRON_INCREMENTAL_DELAY = 160;
|
||||
private static final int CHEVRON_ANIMATION_DURATION = 850;
|
||||
private static final int RETURN_TO_HOME_DELAY = 1200;
|
||||
private static final int RETURN_TO_HOME_DURATION = 300;
|
||||
private static final int RETURN_TO_HOME_DURATION = 200;
|
||||
private static final int HIDE_ANIMATION_DELAY = 200;
|
||||
private static final int HIDE_ANIMATION_DURATION = 200;
|
||||
private static final int SHOW_ANIMATION_DURATION = 200;
|
||||
private static final int SHOW_ANIMATION_DELAY = 50;
|
||||
private static final int INITIAL_SHOW_HANDLE_DURATION = 200;
|
||||
|
||||
private static final float TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.3f;
|
||||
private static final float TARGET_SCALE_SELECTED = 0.8f;
|
||||
private static final long INITIAL_SHOW_HANDLE_DURATION = 200;
|
||||
private static final float TARGET_SCALE_UNSELECTED = 1.0f;
|
||||
private static final float RING_SCALE_UNSELECTED = 0.5f;
|
||||
private static final float RING_SCALE_SELECTED = 1.5f;
|
||||
private static final float TARGET_SCALE_EXPANDED = 1.0f;
|
||||
private static final float TARGET_SCALE_COLLAPSED = 0.8f;
|
||||
private static final float RING_SCALE_EXPANDED = 1.0f;
|
||||
private static final float RING_SCALE_COLLAPSED = 0.5f;
|
||||
|
||||
private TimeInterpolator mChevronAnimationInterpolator = Ease.Quad.easeOut;
|
||||
|
||||
@@ -182,7 +186,7 @@ public class MultiWaveView extends View {
|
||||
if (mNewTargetResources != 0) {
|
||||
internalSetTargetResources(mNewTargetResources);
|
||||
mNewTargetResources = 0;
|
||||
hideTargets(false);
|
||||
hideTargets(false, false);
|
||||
}
|
||||
mAnimatingTargets = false;
|
||||
}
|
||||
@@ -195,6 +199,7 @@ public class MultiWaveView extends View {
|
||||
private int mVerticalInset;
|
||||
private int mGravity = Gravity.TOP;
|
||||
private boolean mInitialLayout = true;
|
||||
private Tweener mBackgroundAnimator;
|
||||
|
||||
public MultiWaveView(Context context) {
|
||||
this(context, null);
|
||||
@@ -358,14 +363,21 @@ public class MultiWaveView extends View {
|
||||
switch (state) {
|
||||
case STATE_IDLE:
|
||||
deactivateTargets();
|
||||
hideTargets(true, false);
|
||||
startBackgroundAnimation(0, 0.0f);
|
||||
mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
|
||||
break;
|
||||
|
||||
case STATE_START:
|
||||
deactivateHandle(0, 0, 1.0f, null);
|
||||
startBackgroundAnimation(0, 0.0f);
|
||||
break;
|
||||
|
||||
case STATE_FIRST_TOUCH:
|
||||
stopHandleAnimation();
|
||||
deactivateTargets();
|
||||
showTargets(true);
|
||||
activateHandle();
|
||||
mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE);
|
||||
startBackgroundAnimation(INITIAL_SHOW_HANDLE_DURATION, 1.0f);
|
||||
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
|
||||
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
|
||||
announceTargets();
|
||||
@@ -384,17 +396,29 @@ public class MultiWaveView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
private void activateHandle() {
|
||||
mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE);
|
||||
if (mAlwaysTrackFinger) {
|
||||
mHandleAnimations.stop();
|
||||
mHandleDrawable.setAlpha(0.0f);
|
||||
mHandleAnimations.add(Tweener.to(mHandleDrawable, INITIAL_SHOW_HANDLE_DURATION,
|
||||
"ease", Ease.Cubic.easeIn,
|
||||
"alpha", 1.0f,
|
||||
"onUpdate", mUpdateListener));
|
||||
mHandleAnimations.start();
|
||||
}
|
||||
private void activateHandle(int duration, int delay, float finalAlpha,
|
||||
AnimatorListener finishListener) {
|
||||
mHandleAnimations.cancel();
|
||||
mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
|
||||
"ease", Ease.Cubic.easeIn,
|
||||
"delay", delay,
|
||||
"alpha", finalAlpha,
|
||||
"onUpdate", mUpdateListener,
|
||||
"onComplete", finishListener));
|
||||
mHandleAnimations.start();
|
||||
}
|
||||
|
||||
private void deactivateHandle(int duration, int delay, float finalAlpha,
|
||||
AnimatorListener finishListener) {
|
||||
mHandleAnimations.cancel();
|
||||
mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
|
||||
"ease", Ease.Quart.easeOut,
|
||||
"delay", delay,
|
||||
"alpha", finalAlpha,
|
||||
"x", 0,
|
||||
"y", 0,
|
||||
"onUpdate", mUpdateListener,
|
||||
"onComplete", finishListener));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,14 +465,6 @@ public class MultiWaveView extends View {
|
||||
mChevronAnimations.start();
|
||||
}
|
||||
|
||||
private void stopChevronAnimation() {
|
||||
mChevronAnimations.stop();
|
||||
}
|
||||
|
||||
private void stopHandleAnimation() {
|
||||
mHandleAnimations.stop();
|
||||
}
|
||||
|
||||
private void deactivateTargets() {
|
||||
final int count = mTargetDrawables.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
@@ -493,39 +509,33 @@ public class MultiWaveView extends View {
|
||||
|
||||
private void doFinish() {
|
||||
final int activeTarget = mActiveTarget;
|
||||
boolean targetHit = activeTarget != -1;
|
||||
final boolean targetHit = activeTarget != -1;
|
||||
|
||||
// Hide unselected targets
|
||||
hideTargets(true);
|
||||
|
||||
// Highlight the selected one
|
||||
mHandleAnimations.cancel();
|
||||
if (targetHit) {
|
||||
mHandleDrawable.setAlpha(0.0f);
|
||||
mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
|
||||
hideUnselected(activeTarget);
|
||||
if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
|
||||
|
||||
highlightSelected(activeTarget);
|
||||
|
||||
// Inform listener of any active targets. Typically only one will be active.
|
||||
if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
|
||||
deactivateHandle(RETURN_TO_HOME_DURATION, RETURN_TO_HOME_DELAY, 0.0f, mResetListener);
|
||||
dispatchTriggerEvent(activeTarget);
|
||||
} else {
|
||||
// Animate handle back to the center based on current state.
|
||||
deactivateHandle(HIDE_ANIMATION_DURATION, HIDE_ANIMATION_DELAY, 1.0f,
|
||||
mResetListenerWithPing);
|
||||
hideTargets(true, false);
|
||||
mHandleAnimations.start();
|
||||
}
|
||||
|
||||
// Animate handle back to the center based on current state.
|
||||
int delay = targetHit ? RETURN_TO_HOME_DELAY : 0;
|
||||
int duration = RETURN_TO_HOME_DURATION;
|
||||
mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
|
||||
"ease", Ease.Quart.easeOut,
|
||||
"delay", delay,
|
||||
"alpha", mAlwaysTrackFinger ? 0.0f : 1.0f,
|
||||
"x", 0,
|
||||
"y", 0,
|
||||
"onUpdate", mUpdateListener,
|
||||
"onComplete", (mDragging && !targetHit) ? mResetListenerWithPing : mResetListener));
|
||||
mHandleAnimations.start();
|
||||
|
||||
setGrabbedState(OnTriggerListener.NO_HANDLE);
|
||||
}
|
||||
|
||||
private void highlightSelected(int activeTarget) {
|
||||
// Highlight the given target and fade others
|
||||
mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
|
||||
hideUnselected(activeTarget);
|
||||
}
|
||||
|
||||
private void hideUnselected(int active) {
|
||||
for (int i = 0; i < mTargetDrawables.size(); i++) {
|
||||
if (i != active) {
|
||||
@@ -535,16 +545,15 @@ public class MultiWaveView extends View {
|
||||
mOuterRing.setAlpha(0.0f);
|
||||
}
|
||||
|
||||
private void hideTargets(boolean animate) {
|
||||
private void hideTargets(boolean animate, boolean expanded) {
|
||||
mTargetAnimations.cancel();
|
||||
// Note: these animations should complete at the same time so that we can swap out
|
||||
// the target assets asynchronously from the setTargetResources() call.
|
||||
mAnimatingTargets = animate;
|
||||
final int duration = animate ? HIDE_ANIMATION_DURATION : 0;
|
||||
final int delay = animate ? HIDE_ANIMATION_DELAY : 0;
|
||||
final boolean targetSelected = mActiveTarget != -1;
|
||||
|
||||
final float targetScale = targetSelected ? TARGET_SCALE_SELECTED : TARGET_SCALE_UNSELECTED;
|
||||
final float targetScale = expanded ? TARGET_SCALE_EXPANDED : TARGET_SCALE_COLLAPSED;
|
||||
final int length = mTargetDrawables.size();
|
||||
for (int i = 0; i < length; i++) {
|
||||
TargetDrawable target = mTargetDrawables.get(i);
|
||||
@@ -558,7 +567,7 @@ public class MultiWaveView extends View {
|
||||
"onUpdate", mUpdateListener));
|
||||
}
|
||||
|
||||
final float ringScaleTarget = targetSelected ? RING_SCALE_SELECTED : RING_SCALE_UNSELECTED;
|
||||
final float ringScaleTarget = expanded ? RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED;
|
||||
mTargetAnimations.add(Tweener.to(mOuterRing, duration,
|
||||
"ease", Ease.Cubic.easeOut,
|
||||
"alpha", 0.0f,
|
||||
@@ -580,8 +589,6 @@ public class MultiWaveView extends View {
|
||||
for (int i = 0; i < length; i++) {
|
||||
TargetDrawable target = mTargetDrawables.get(i);
|
||||
target.setState(TargetDrawable.STATE_INACTIVE);
|
||||
target.setScaleX(TARGET_SCALE_SELECTED);
|
||||
target.setScaleY(TARGET_SCALE_SELECTED);
|
||||
mTargetAnimations.add(Tweener.to(target, duration,
|
||||
"ease", Ease.Cubic.easeOut,
|
||||
"alpha", 1.0f,
|
||||
@@ -732,17 +739,30 @@ public class MultiWaveView extends View {
|
||||
* @param animate
|
||||
*/
|
||||
public void reset(boolean animate) {
|
||||
stopChevronAnimation();
|
||||
stopHandleAnimation();
|
||||
mChevronAnimations.stop();
|
||||
mHandleAnimations.stop();
|
||||
mTargetAnimations.stop();
|
||||
startBackgroundAnimation(0, 0.0f);
|
||||
hideChevrons();
|
||||
hideTargets(animate);
|
||||
mHandleDrawable.setX(0);
|
||||
mHandleDrawable.setY(0);
|
||||
mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
|
||||
hideTargets(animate, false);
|
||||
deactivateHandle(0, 0, 1.0f, null);
|
||||
Tweener.reset();
|
||||
}
|
||||
|
||||
private void startBackgroundAnimation(int duration, float alpha) {
|
||||
Drawable background = getBackground();
|
||||
if (mAlwaysTrackFinger && background != null) {
|
||||
if (mBackgroundAnimator != null) {
|
||||
mBackgroundAnimator.animator.end();
|
||||
}
|
||||
mBackgroundAnimator = Tweener.to(background, duration,
|
||||
"ease", Ease.Cubic.easeIn,
|
||||
"alpha", new int[] {0, (int)(255.0f * alpha)},
|
||||
"delay", SHOW_ANIMATION_DELAY);
|
||||
mBackgroundAnimator.animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
final int action = event.getAction();
|
||||
@@ -784,7 +804,10 @@ public class MultiWaveView extends View {
|
||||
}
|
||||
|
||||
private void handleDown(MotionEvent event) {
|
||||
if (!trySwitchToFirstTouchState(event.getX(), event.getY())) {
|
||||
float eventX = event.getX();
|
||||
float eventY = event.getY();
|
||||
switchToState(STATE_START, eventX, eventY);
|
||||
if (!trySwitchToFirstTouchState(eventX, eventY)) {
|
||||
mDragging = false;
|
||||
mTargetAnimations.cancel();
|
||||
ping();
|
||||
@@ -830,7 +853,9 @@ public class MultiWaveView extends View {
|
||||
|
||||
if (!mDragging) {
|
||||
trySwitchToFirstTouchState(eventX, eventY);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (mDragging) {
|
||||
if (singleTarget) {
|
||||
// Snap to outer ring if there's only one target
|
||||
float snapRadius = mOuterRadius - mSnapMargin;
|
||||
@@ -865,17 +890,11 @@ public class MultiWaveView extends View {
|
||||
if (activeTarget != -1) {
|
||||
switchToState(STATE_SNAP, x,y);
|
||||
TargetDrawable target = targets.get(activeTarget);
|
||||
float newX = singleTarget ? x : target.getX();
|
||||
float newY = singleTarget ? y : target.getY();
|
||||
final float newX = singleTarget ? x : target.getX();
|
||||
final float newY = singleTarget ? y : target.getY();
|
||||
moveHandleTo(newX, newY, false);
|
||||
mHandleAnimations.cancel();
|
||||
mHandleDrawable.setAlpha(0.0f);
|
||||
} else {
|
||||
switchToState(STATE_TRACKING, x, y);
|
||||
if (mActiveTarget != -1) {
|
||||
mHandleAnimations.cancel();
|
||||
mHandleDrawable.setAlpha(1.0f);
|
||||
}
|
||||
moveHandleTo(x, y, false);
|
||||
}
|
||||
|
||||
@@ -900,6 +919,9 @@ public class MultiWaveView extends View {
|
||||
String targetContentDescription = getTargetDescription(activeTarget);
|
||||
announceText(targetContentDescription);
|
||||
}
|
||||
activateHandle(0, 0, 0.0f, null);
|
||||
} else {
|
||||
activateHandle(0, 0, 1.0f, null);
|
||||
}
|
||||
}
|
||||
mActiveTarget = activeTarget;
|
||||
@@ -1021,7 +1043,7 @@ public class MultiWaveView extends View {
|
||||
|
||||
if (mInitialLayout) {
|
||||
hideChevrons();
|
||||
hideTargets(false);
|
||||
hideTargets(false, false);
|
||||
moveHandleTo(0, 0, false);
|
||||
mInitialLayout = false;
|
||||
}
|
||||
|
||||
@@ -83,6 +83,9 @@ class Tweener {
|
||||
} else if (value instanceof float[]) {
|
||||
props.add(PropertyValuesHolder.ofFloat(key,
|
||||
((float[])value)[0], ((float[])value)[1]));
|
||||
} else if (value instanceof int[]) {
|
||||
props.add(PropertyValuesHolder.ofInt(key,
|
||||
((int[])value)[0], ((int[])value)[1]));
|
||||
} else if (value instanceof Number) {
|
||||
float floatValue = ((Number)value).floatValue();
|
||||
props.add(PropertyValuesHolder.ofFloat(key, floatValue));
|
||||
|
||||
@@ -22,53 +22,26 @@
|
||||
xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/search_panel_container"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingBottom="0dip">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/search_bg_protect"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.android.internal.widget.multiwaveview.MultiWaveView
|
||||
android:id="@+id/multi_wave_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/navbar_search_panel_height"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:gravity="center_horizontal|top"
|
||||
android:background="@drawable/navbar_search_bg_scrim"
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/search_panel_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true">
|
||||
|
||||
<View
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:layout_alignTop="@id/multi_wave_view"
|
||||
android:layout_alignLeft="@id/multi_wave_view"
|
||||
android:layout_alignRight="@id/multi_wave_view"
|
||||
android:layout_alignBottom="@id/multi_wave_view"
|
||||
android:layout_marginBottom="@dimen/navigation_bar_size"
|
||||
android:background="@drawable/navbar_search_bg_scrim"/>
|
||||
|
||||
<com.android.internal.widget.multiwaveview.MultiWaveView
|
||||
android:id="@+id/multi_wave_view"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/navbar_search_panel_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="top"
|
||||
|
||||
prvandroid:targetDrawables="@array/navbar_search_targets"
|
||||
prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
|
||||
prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
|
||||
prvandroid:handleDrawable="@drawable/navbar_search_handle"
|
||||
prvandroid:waveDrawable="@drawable/navbar_search_outerring"
|
||||
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
|
||||
prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
|
||||
prvandroid:feedbackCount="0"
|
||||
prvandroid:vibrationDuration="@integer/config_vibration_duration"
|
||||
prvandroid:alwaysTrackFinger="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
prvandroid:targetDrawables="@array/navbar_search_targets"
|
||||
prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
|
||||
prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
|
||||
prvandroid:handleDrawable="@drawable/navbar_search_handle"
|
||||
prvandroid:waveDrawable="@drawable/navbar_search_outerring"
|
||||
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
|
||||
prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
|
||||
prvandroid:feedbackCount="0"
|
||||
prvandroid:vibrationDuration="@integer/config_vibration_duration"
|
||||
prvandroid:alwaysTrackFinger="true"/>
|
||||
|
||||
</com.android.systemui.SearchPanelView>
|
||||
|
||||
@@ -22,53 +22,27 @@
|
||||
xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/search_panel_container"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingBottom="0dip">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/search_bg_protect"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.android.internal.widget.multiwaveview.MultiWaveView
|
||||
android:id="@+id/multi_wave_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/navbar_search_panel_height"
|
||||
android:layout_gravity="left|bottom"
|
||||
android:gravity="top|right"
|
||||
android:layout_marginLeft="-150dip"
|
||||
android:background="@drawable/navbar_search_bg_scrim"
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/search_panel_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/navbar_search_panel_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="-120dip">
|
||||
|
||||
<View
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:layout_alignTop="@id/multi_wave_view"
|
||||
android:layout_alignLeft="@id/multi_wave_view"
|
||||
android:layout_alignRight="@id/multi_wave_view"
|
||||
android:layout_alignBottom="@id/multi_wave_view"
|
||||
android:layout_marginBottom="@dimen/navigation_bar_size"
|
||||
android:background="@drawable/navbar_search_bg_scrim"/>
|
||||
|
||||
<com.android.internal.widget.multiwaveview.MultiWaveView
|
||||
android:id="@+id/multi_wave_view"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
|
||||
prvandroid:targetDrawables="@array/navbar_search_targets"
|
||||
prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
|
||||
prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
|
||||
prvandroid:handleDrawable="@drawable/navbar_search_handle"
|
||||
prvandroid:waveDrawable="@drawable/navbar_search_outerring"
|
||||
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
|
||||
prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
|
||||
prvandroid:feedbackCount="0"
|
||||
prvandroid:vibrationDuration="@integer/config_vibration_duration"
|
||||
prvandroid:alwaysTrackFinger="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
prvandroid:targetDrawables="@array/navbar_search_targets"
|
||||
prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
|
||||
prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
|
||||
prvandroid:handleDrawable="@drawable/navbar_search_handle"
|
||||
prvandroid:waveDrawable="@drawable/navbar_search_outerring"
|
||||
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
|
||||
prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
|
||||
prvandroid:feedbackCount="0"
|
||||
prvandroid:vibrationDuration="@integer/config_vibration_duration"
|
||||
prvandroid:alwaysTrackFinger="true"/>
|
||||
|
||||
</com.android.systemui.SearchPanelView>
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -38,7 +37,6 @@ import android.widget.FrameLayout;
|
||||
|
||||
import com.android.internal.widget.multiwaveview.MultiWaveView;
|
||||
import com.android.internal.widget.multiwaveview.MultiWaveView.OnTriggerListener;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recent.StatusBarTouchProxy;
|
||||
import com.android.systemui.statusbar.BaseStatusBar;
|
||||
@@ -47,7 +45,8 @@ import com.android.systemui.statusbar.tablet.StatusBarPanel;
|
||||
import com.android.systemui.statusbar.tablet.TabletStatusBar;
|
||||
|
||||
public class SearchPanelView extends FrameLayout implements
|
||||
StatusBarPanel, Animator.AnimatorListener {
|
||||
StatusBarPanel {
|
||||
private static final int SEARCH_PANEL_HOLD_DURATION = 500;
|
||||
static final String TAG = "SearchPanelView";
|
||||
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
|
||||
private Context mContext;
|
||||
@@ -123,7 +122,7 @@ public class SearchPanelView extends FrameLayout implements
|
||||
final MultiWaveView.OnTriggerListener mMultiWaveViewListener
|
||||
= new MultiWaveView.OnTriggerListener() {
|
||||
|
||||
private int mTarget = -1;
|
||||
private boolean mWaitingForLaunch;
|
||||
|
||||
public void onGrabbed(View v, int handle) {
|
||||
}
|
||||
@@ -132,26 +131,28 @@ public class SearchPanelView extends FrameLayout implements
|
||||
}
|
||||
|
||||
public void onGrabbedStateChange(View v, int handle) {
|
||||
if (mTarget == -1 && OnTriggerListener.NO_HANDLE == handle) {
|
||||
if (!mWaitingForLaunch && OnTriggerListener.NO_HANDLE == handle) {
|
||||
mBar.hideSearchPanel();
|
||||
}
|
||||
}
|
||||
|
||||
public void onTrigger(View v, int target) {
|
||||
mTarget = target;
|
||||
public void onTrigger(View v, final int target) {
|
||||
final int resId = mMultiWaveView.getResourceIdForTarget(target);
|
||||
switch (resId) {
|
||||
case com.android.internal.R.drawable.ic_lockscreen_search:
|
||||
mWaitingForLaunch = true;
|
||||
startAssistActivity();
|
||||
postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
mWaitingForLaunch = false;
|
||||
mBar.hideSearchPanel();
|
||||
}
|
||||
}, SEARCH_PANEL_HOLD_DURATION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onFinishFinalAnimation() {
|
||||
if (mTarget != -1) {
|
||||
final int resId = mMultiWaveView.getResourceIdForTarget(mTarget);
|
||||
mTarget = -1; // a safety to make sure we never launch w/o prior call to onTrigger
|
||||
switch (resId) {
|
||||
case com.android.internal.R.drawable.ic_lockscreen_search:
|
||||
startAssistActivity();
|
||||
break;
|
||||
}
|
||||
mBar.hideSearchPanel();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -194,15 +195,11 @@ public class SearchPanelView extends FrameLayout implements
|
||||
};
|
||||
|
||||
public void show(final boolean show, boolean animate) {
|
||||
if (animate) {
|
||||
if (mShowing != show) {
|
||||
mShowing = show;
|
||||
// TODO: start animating ring
|
||||
}
|
||||
} else {
|
||||
mShowing = show;
|
||||
onAnimationEnd(null);
|
||||
if (!show) {
|
||||
final LayoutTransition transitioner = animate ? createLayoutTransitioner() : null;
|
||||
((ViewGroup)mSearchTargetsContainer).setLayoutTransition(transitioner);
|
||||
}
|
||||
mShowing = show;
|
||||
if (show) {
|
||||
if (getVisibility() != View.VISIBLE) {
|
||||
setVisibility(View.VISIBLE);
|
||||
@@ -228,25 +225,6 @@ public class SearchPanelView extends FrameLayout implements
|
||||
}
|
||||
}
|
||||
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mShowing) {
|
||||
final LayoutTransition transitioner = new LayoutTransition();
|
||||
((ViewGroup)mSearchTargetsContainer).setLayoutTransition(transitioner);
|
||||
createCustomAnimations(transitioner);
|
||||
} else {
|
||||
((ViewGroup)mSearchTargetsContainer).setLayoutTransition(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to be aligned at the bottom. LinearLayout can't do this, so instead,
|
||||
* let LinearLayout do all the hard work, and then shift everything down to the bottom.
|
||||
@@ -293,9 +271,11 @@ public class SearchPanelView extends FrameLayout implements
|
||||
}
|
||||
}
|
||||
|
||||
private void createCustomAnimations(LayoutTransition transitioner) {
|
||||
private LayoutTransition createLayoutTransitioner() {
|
||||
LayoutTransition transitioner = new LayoutTransition();
|
||||
transitioner.setDuration(200);
|
||||
transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
|
||||
transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
|
||||
return transitioner;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,14 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
|
||||
@Override
|
||||
public void showSearchPanel() {
|
||||
super.showSearchPanel();
|
||||
// XXX This is a bit of a hack. Since navbar is no longer slippery, we use the
|
||||
// gesture to dismiss the expanded statusbar.
|
||||
if (mExpanded) {
|
||||
animateCollapse();
|
||||
return;
|
||||
} else {
|
||||
super.showSearchPanel();
|
||||
}
|
||||
WindowManager.LayoutParams lp =
|
||||
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
|
||||
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||
@@ -506,7 +513,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
public int getStatusBarHeight() {
|
||||
if (mNaturalBarHeight < 0) {
|
||||
final Resources res = mContext.getResources();
|
||||
mNaturalBarHeight =
|
||||
mNaturalBarHeight =
|
||||
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
|
||||
}
|
||||
return mNaturalBarHeight;
|
||||
@@ -526,7 +533,9 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch(event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
showSearchPanel();
|
||||
if (!shouldDisableNavbarGestures()) {
|
||||
showSearchPanel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -674,9 +683,9 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
if (INTRUDER_ALERT_DECAY_MS > 0) {
|
||||
mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
|
||||
}
|
||||
} else
|
||||
} else
|
||||
*/
|
||||
|
||||
|
||||
if (notification.notification.fullScreenIntent != null) {
|
||||
// not immersive & a full-screen alert should be shown
|
||||
Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
|
||||
@@ -906,7 +915,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
|
||||
flagdbg.append(">");
|
||||
Slog.d(TAG, flagdbg.toString());
|
||||
|
||||
|
||||
if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
mIcons.animate().cancel();
|
||||
if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
@@ -1016,7 +1025,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
if (mExpandedVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mExpandedVisible = true;
|
||||
mNotificationPanel.setVisibility(View.VISIBLE);
|
||||
|
||||
@@ -1213,7 +1222,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
//Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
|
||||
// + " mAnimAccel=" + mAnimAccel);
|
||||
}
|
||||
|
||||
|
||||
void doRevealAnimation(long frameTimeNanos) {
|
||||
if (SPEW) {
|
||||
Slog.d(TAG, "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos));
|
||||
@@ -1465,11 +1474,11 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
mTicker.halt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mNavigationBarView != null) {
|
||||
mNavigationBarView.setLowProfile(lightsOut);
|
||||
}
|
||||
|
||||
|
||||
setStatusBarLowProfile(lightsOut);
|
||||
}
|
||||
|
||||
@@ -1494,7 +1503,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
|
||||
);
|
||||
mLightsOutAnimation.setDuration(750);
|
||||
|
||||
|
||||
mLightsOnAnimation = new AnimatorSet();
|
||||
mLightsOnAnimation.playTogether(
|
||||
ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
|
||||
@@ -1505,7 +1514,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
);
|
||||
mLightsOnAnimation.setDuration(250);
|
||||
}
|
||||
|
||||
|
||||
mLightsOutAnimation.cancel();
|
||||
mLightsOnAnimation.cancel();
|
||||
|
||||
@@ -1518,7 +1527,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
private boolean areLightsOn() {
|
||||
return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
||||
}
|
||||
|
||||
|
||||
public void setLightsOn(boolean on) {
|
||||
Log.v(TAG, "setLightsOn(" + on + ")");
|
||||
if (on) {
|
||||
@@ -1622,7 +1631,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
|
||||
// no ticking in lights-out mode
|
||||
if (!areLightsOn()) return;
|
||||
|
||||
|
||||
// Show the ticker if one is requested. Also don't do this
|
||||
// until status bar window is attached to the window manager,
|
||||
// because... well, what's the point otherwise? And trying to
|
||||
@@ -1822,7 +1831,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
}
|
||||
|
||||
int panelh = 0;
|
||||
|
||||
final int disph = getExpandedViewMaxHeight();
|
||||
|
||||
// If the expanded view is not visible, make sure they're still off screen.
|
||||
@@ -2039,7 +2047,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
try {
|
||||
mBarService.onNotificationClear(
|
||||
mCurrentlyIntrudingNotification.pkg,
|
||||
mCurrentlyIntrudingNotification.tag,
|
||||
mCurrentlyIntrudingNotification.tag,
|
||||
mCurrentlyIntrudingNotification.id);
|
||||
} catch (android.os.RemoteException ex) {
|
||||
// oh well
|
||||
@@ -2095,14 +2103,14 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
|
||||
|
||||
mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
|
||||
|
||||
|
||||
mNotificationPanelMarginBottomPx
|
||||
= (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
|
||||
mNotificationPanelMarginLeftPx
|
||||
= (int) res.getDimension(R.dimen.notification_panel_margin_left);
|
||||
mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
|
||||
if (mNotificationPanelGravity <= 0) {
|
||||
mNotificationPanelGravity = Gravity.CENTER_VERTICAL | Gravity.TOP;
|
||||
mNotificationPanelGravity = Gravity.CENTER_VERTICAL | Gravity.TOP;
|
||||
}
|
||||
|
||||
if (false) Slog.v(TAG, "updateResources");
|
||||
|
||||
@@ -192,7 +192,9 @@ public class TabletStatusBar extends BaseStatusBar implements
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch(event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
showSearchPanel();
|
||||
if (!shouldDisableNavbarGestures()) {
|
||||
showSearchPanel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -254,12 +256,12 @@ public class TabletStatusBar extends BaseStatusBar implements
|
||||
|
||||
// network icons: either a combo icon that switches between mobile and data, or distinct
|
||||
// mobile and data icons
|
||||
final ImageView mobileRSSI =
|
||||
final ImageView mobileRSSI =
|
||||
(ImageView)mNotificationPanel.findViewById(R.id.mobile_signal);
|
||||
if (mobileRSSI != null) {
|
||||
mNetworkController.addPhoneSignalIconView(mobileRSSI);
|
||||
}
|
||||
final ImageView wifiRSSI =
|
||||
final ImageView wifiRSSI =
|
||||
(ImageView)mNotificationPanel.findViewById(R.id.wifi_signal);
|
||||
if (wifiRSSI != null) {
|
||||
mNetworkController.addWifiIconView(wifiRSSI);
|
||||
@@ -493,7 +495,7 @@ public class TabletStatusBar extends BaseStatusBar implements
|
||||
mBluetoothController.addIconView((ImageView)sb.findViewById(R.id.bluetooth));
|
||||
|
||||
mNetworkController = new NetworkController(mContext);
|
||||
final SignalClusterView signalCluster =
|
||||
final SignalClusterView signalCluster =
|
||||
(SignalClusterView)sb.findViewById(R.id.signal_cluster);
|
||||
mNetworkController.addSignalCluster(signalCluster);
|
||||
|
||||
@@ -1061,7 +1063,7 @@ public class TabletStatusBar extends BaseStatusBar implements
|
||||
if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
|
||||
mHandler.removeMessages(MSG_HIDE_CHROME);
|
||||
mHandler.removeMessages(MSG_SHOW_CHROME);
|
||||
mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
|
||||
mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
|
||||
? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user