summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml27
-rw-r--r--packages/SystemUI/res/drawable/recents_thumbnail_layers.xml19
-rw-r--r--packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml19
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_recent_item.xml5
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_recent_panel.xml1
-rw-r--r--packages/SystemUI/res/layout-port/status_bar_recent_item.xml4
-rw-r--r--packages/SystemUI/res/layout-port/status_bar_recent_panel.xml1
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml4
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml1
-rw-r--r--packages/SystemUI/res/menu/recent_popup_menu.xml (renamed from packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml)8
-rw-r--r--packages/SystemUI/res/values/strings.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/Choreographer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java113
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java110
16 files changed, 262 insertions, 136 deletions
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml
deleted file mode 100644
index 0e58e12..0000000
--- a/packages/SystemUI/res/drawable/recents_thumbnail_bg_selector.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-
- <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
-
- <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
- <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
- <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
- <item android:state_focused="true" android:drawable="@drawable/recents_thumbnail_bg_holo" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml b/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml
new file mode 100644
index 0000000..6cae2c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:drawable="@drawable/recents_thumbnail_bg" android:id="@+id/base_layer"/>
+ <item android:drawable="@drawable/recents_thumbnail_overlay" android:id="@+id/overlay_layer"/>
+</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml b/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml
new file mode 100644
index 0000000..200bac4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_pressed="true" />
+ <item android:drawable="@*android:color/transparent"/>
+</selector>
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index be4f1d7..8c29042 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -24,14 +24,15 @@
android:layout_height="wrap_content"
android:layout_width="@dimen/status_bar_recents_thumbnail_view_width">
- <ImageView android:id="@+id/app_thumbnail"
+ <FrameLayout android:id="@+id/app_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
- android:background="@drawable/recents_thumbnail_bg_selector"
+ android:clickable="true"
+ android:background="@drawable/recents_thumbnail_layers"
/>
<ImageView android:id="@+id/app_icon"
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index efdd9ac..20ef7cf 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -51,7 +51,6 @@
android:fadingEdge="horizontal"
android:scrollbars="none"
android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
- android:listSelector="@drawable/recents_thumbnail_bg_selector"
android:layout_gravity="bottom|left"
android:orientation="horizontal"
android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index 76965c9..c705a69 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -24,13 +24,15 @@
android:layout_height="wrap_content"
android:layout_width="@dimen/status_bar_recents_thumbnail_view_width">
- <ImageView android:id="@+id/app_thumbnail"
+ <FrameLayout android:id="@+id/app_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
+ android:clickable="true"
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
+ android:background="@drawable/recents_thumbnail_layers"
/>
<ImageView android:id="@+id/app_icon"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index 28ef239..c680b8e 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -48,7 +48,6 @@
android:fadingEdge="vertical"
android:scrollbars="none"
android:fadingEdgeLength="@*android:dimen/status_bar_height"
- android:listSelector="@drawable/recents_thumbnail_bg_selector"
android:layout_gravity="bottom|left"
android:clipToPadding="false"
android:clipChildren="false">
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index 9687866..386ce30 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -24,13 +24,15 @@
android:layout_height="wrap_content"
android:layout_width="@dimen/status_bar_recents_thumbnail_view_width">
- <ImageView android:id="@+id/app_thumbnail"
+ <FrameLayout android:id="@+id/app_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
+ android:clickable="true"
+ android:background="@drawable/recents_thumbnail_layers"
/>
<ImageView android:id="@+id/app_icon"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
index 75fdc67..2c9a152 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
@@ -56,7 +56,6 @@
android:scrollbars="none"
android:fadingEdgeLength="20dip"
android:layout_gravity="bottom|left"
- android:listSelector="@drawable/recents_thumbnail_bg_selector"
android:clipToPadding="false"
android:clipChildren="false">
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml b/packages/SystemUI/res/menu/recent_popup_menu.xml
index f9bba2a..eecfb9a 100644
--- a/packages/SystemUI/res/drawable/recents_thumbnail_bg_holo.xml
+++ b/packages/SystemUI/res/menu/recent_popup_menu.xml
@@ -17,7 +17,7 @@
** limitations under the License.
*/
-->
-<transition xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/recents_thumbnail_bg_press"/>
- <item android:drawable="@drawable/recents_thumbnail_bg_press"/>
-</transition>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/recent_remove_item" android:title="@string/status_bar_recent_remove_item_title" />
+ <item android:id="@+id/recent_inspect_item" android:title="@string/status_bar_recent_inspect_item_title" />
+</menu>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 882455e..01cf2dc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -35,6 +35,14 @@
shown again. [CHAR LIMIT=25] -->
<string name="status_bar_please_disturb_button">Show notifications</string>
+ <!-- Title shown in recents popup for removing an application from the list -->
+ <string name="status_bar_recent_remove_item_title">Remove</string>
+
+ <!-- Title shown in recents popup for inspecting an application's properties -->
+ <string name="status_bar_recent_inspect_item_title">Inspect</string>
+
+
+
<!-- The label in the bar at the top of the status bar when there are no notifications
showing. [CHAR LIMIT=40]-->
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
index 37a9913..2d327c4 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
@@ -53,8 +53,6 @@ import android.view.View;
void createAnimation(boolean appearing) {
float start, end;
- if (RecentsPanelView.DEBUG) Log.e(TAG, "createAnimation()", new Exception());
-
// 0: on-screen
// height: off-screen
float y = mContentView.getTranslationY();
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
index 5d29e2a..797f94c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
@@ -26,5 +26,5 @@ public interface RecentsCallback {
void handleOnClick(View selectedView);
void handleSwipe(View selectedView, int direction);
- void handleLongPress(View selectedView);
+ void handleLongPress(View selectedView, View anchorView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index f984aac..12d6cd9 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -20,6 +20,7 @@ import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -30,7 +31,6 @@ import android.database.DataSetObserver;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -42,10 +42,9 @@ import android.widget.LinearLayout;
import com.android.systemui.R;
-public class RecentsHorizontalScrollView extends HorizontalScrollView
- implements View.OnClickListener, View.OnTouchListener {
- private static final boolean DEBUG_INVALIDATE = false;
+public class RecentsHorizontalScrollView extends HorizontalScrollView {
private static final String TAG = RecentsPanelView.TAG;
+ private static final boolean DEBUG_INVALIDATE = false;
private static final boolean DEBUG = RecentsPanelView.DEBUG;
private LinearLayout mLinearLayout;
private ActivityDescriptionAdapter mAdapter;
@@ -57,6 +56,15 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
private VelocityTracker mVelocityTracker;
private float mDensityScale;
private float mPagingTouchSlop;
+ private OnLongClickListener mOnLongClick = new OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ final View anchorView = v.findViewById(R.id.app_description);
+ mCurrentView = v;
+ mCallback.handleLongPress(v, anchorView);
+ mCurrentView = null; // make sure we don't accept the return click from this
+ return true;
+ }
+ };
public RecentsHorizontalScrollView(Context context) {
this(context, null);
@@ -72,13 +80,12 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
return mLinearLayout.getWidth() - getWidth();
}
- public void update() {
+ private void update() {
mLinearLayout.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
- View view = mAdapter.getView(i, null, mLinearLayout);
+ final View view = mAdapter.getView(i, null, mLinearLayout);
view.setClickable(true);
- view.setOnClickListener(this);
- view.setOnTouchListener(this);
+ view.setOnLongClickListener(mOnLongClick);
mLinearLayout.addView(view);
}
// Scroll to end after layout.
@@ -91,7 +98,20 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
}
@Override
+ public void removeViewInLayout(final View view) {
+ ObjectAnimator anim = animateClosed(view, Constants.MAX_ESCAPE_ANIMATION_DURATION,
+ "y", view.getY(), view.getY() + view.getHeight());
+ anim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ RecentsHorizontalScrollView.super.removeViewInLayout(view);
+ }
+ });
+ anim.start();
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
@@ -100,6 +120,18 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
case MotionEvent.ACTION_DOWN:
mDragging = false;
mLastY = ev.getY();
+ final float x = ev.getX() + getScrollX();
+ final float y = ev.getY() + getScrollY();
+ mCurrentView = null;
+ for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
+ View item = mLinearLayout.getChildAt(i);
+ if (x >= item.getLeft() && x < item.getRight()
+ && y >= item.getTop() && y < item.getBottom()) {
+ mCurrentView = item;
+ if (DEBUG) Log.v(TAG, "Hit item " + item);
+ break;
+ }
+ }
break;
case MotionEvent.ACTION_MOVE:
@@ -111,6 +143,9 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
break;
case MotionEvent.ACTION_UP:
+ if (mCurrentView != null) {
+ mCallback.handleOnClick(mCurrentView);
+ }
mDragging = false;
break;
}
@@ -125,7 +160,6 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
} else if (view.getY() < thumbHeight * (1.0f - Constants.ALPHA_FADE_START)) {
result = 1.0f + (thumbHeight * Constants.ALPHA_FADE_START + view.getY()) / fadeHeight;
}
- if (DEBUG) Log.v(TAG, "FADE AMOUNT: " + result);
return result;
}
@@ -138,12 +172,12 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
mVelocityTracker.addMovement(ev);
final View animView = mCurrentView;
- // TODO: Cache thumbnail
- final View thumb = animView.findViewById(R.id.app_thumbnail);
+
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
if (animView != null) {
final float delta = ev.getY() - mLastY;
+ final View thumb = animView.findViewById(R.id.app_thumbnail);
animView.setY(animView.getY() + delta);
animView.setAlpha(getAlphaForOffset(animView, thumb.getHeight()));
invalidateGlobalRegion(animView);
@@ -167,35 +201,18 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
long duration =
(long) (Math.abs(newY - curY) * 1000.0f / Math.abs(velocityY));
duration = Math.min(duration, Constants.MAX_ESCAPE_ANIMATION_DURATION);
- anim = ObjectAnimator.ofFloat(animView, "y", curY, newY);
- anim.setInterpolator(new LinearInterpolator());
- final int swipeDirection = animView.getY() >= 0.0f ?
- RecentsCallback.SWIPE_RIGHT : RecentsCallback.SWIPE_LEFT;
- anim.addListener(new AnimatorListener() {
- public void onAnimationStart(Animator animation) {
- }
- public void onAnimationRepeat(Animator animation) {
- }
- public void onAnimationEnd(Animator animation) {
- mLinearLayout.removeView(mCurrentView);
- mCallback.handleSwipe(animView, swipeDirection);
- }
- public void onAnimationCancel(Animator animation) {
- mLinearLayout.removeView(mCurrentView);
- mCallback.handleSwipe(animView, swipeDirection);
- }
- });
- anim.setDuration(duration);
+ anim = animateClosed(animView, duration, "y", curY, newY);
} else { // Animate back to position
long duration = Math.abs(velocityY) > 0.0f ?
(long) (Math.abs(newY - curY) * 1000.0f / Math.abs(velocityY))
: Constants.SNAP_BACK_DURATION;
duration = Math.min(duration, Constants.SNAP_BACK_DURATION);
anim = ObjectAnimator.ofFloat(animView, "y", animView.getY(), 0.0f);
- anim.setInterpolator(new DecelerateInterpolator(2.0f));
+ anim.setInterpolator(new DecelerateInterpolator(4.0f));
anim.setDuration(duration);
}
+ final View thumb = animView.findViewById(R.id.app_thumbnail);
anim.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
animView.setAlpha(getAlphaForOffset(animView, thumb.getHeight()));
@@ -212,6 +229,26 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
return true;
}
+ private ObjectAnimator animateClosed(final View animView, long duration,
+ String attr, float from, float to) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(animView, attr, from, to);
+ anim.setInterpolator(new LinearInterpolator());
+ final int swipeDirection = animView.getX() >= 0.0f ?
+ RecentsCallback.SWIPE_RIGHT : RecentsCallback.SWIPE_LEFT;
+ anim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ mLinearLayout.removeView(animView);
+ mCallback.handleSwipe(animView, swipeDirection);
+ }
+ public void onAnimationCancel(Animator animation) {
+ mLinearLayout.removeView(animView);
+ mCallback.handleSwipe(animView, swipeDirection);
+ }
+ });
+ anim.setDuration(duration);
+ return anim;
+ }
+
void invalidateGlobalRegion(View view) {
RectF childBounds
= new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
@@ -236,13 +273,8 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- LayoutInflater inflater = (LayoutInflater)
- mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
setScrollbarFadingEnabled(true);
-
mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout);
-
final int leftPadding = mContext.getResources()
.getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin);
setOverScrollEffectPadding(leftPadding, 0);
@@ -306,16 +338,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
mLinearLayout.setLayoutTransition(transition);
}
- public void onClick(View view) {
- mCallback.handleOnClick(view);
- }
-
public void setCallback(RecentsCallback callback) {
mCallback = callback;
}
-
- public boolean onTouch(View v, MotionEvent event) {
- mCurrentView = v;
- return false;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index a55fe9c..bc0a508 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -22,6 +22,7 @@ import java.util.List;
import android.animation.Animator;
import android.animation.LayoutTransition;
import android.app.ActivityManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -39,16 +40,22 @@ import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.net.Uri;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
+import android.widget.Button;
import android.widget.ImageView;
+import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -69,7 +76,7 @@ public class RecentsPanelView extends RelativeLayout
private int mIconDpi;
private View mRecentsScrim;
private View mRecentsGlowView;
- private View mRecentsContainer;
+ private ViewGroup mRecentsContainer;
private Bitmap mGlowBitmap;
// TODO: add these widgets attributes to the layout file
private int mGlowBitmapPaddingLeftPx;
@@ -107,8 +114,18 @@ public class RecentsPanelView extends RelativeLayout
}
};
+ private final class OnLongClickDelegate implements View.OnLongClickListener {
+ View mOtherView;
+ OnLongClickDelegate(View other) {
+ mOtherView = other;
+ }
+ public boolean onLongClick(View v) {
+ return mOtherView.performLongClick();
+ }
+ }
+
/* package */ final static class ViewHolder {
- ImageView thumbnailView;
+ View thumbnailView;
ImageView iconView;
TextView labelView;
TextView descriptionView;
@@ -139,7 +156,7 @@ public class RecentsPanelView extends RelativeLayout
if (convertView == null) {
convertView = mInflater.inflate(R.layout.status_bar_recent_item, null);
holder = new ViewHolder();
- holder.thumbnailView = (ImageView) convertView.findViewById(R.id.app_thumbnail);
+ holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail);
holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
@@ -153,11 +170,12 @@ public class RecentsPanelView extends RelativeLayout
final ActivityDescription activityDescription = mActivityDescriptions.get(activityId);
final Bitmap thumb = activityDescription.thumbnail;
- holder.thumbnailView.setImageBitmap(compositeBitmap(mGlowBitmap, thumb));
+ updateDrawable(holder.thumbnailView, compositeBitmap(mGlowBitmap, thumb));
holder.iconView.setImageDrawable(activityDescription.icon);
holder.labelView.setText(activityDescription.label);
holder.descriptionView.setText(activityDescription.description);
holder.thumbnailView.setTag(activityDescription);
+ holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
holder.activityDescription = activityDescription;
return convertView;
@@ -174,6 +192,20 @@ public class RecentsPanelView extends RelativeLayout
return x >= l && x < r && y >= t && y < b;
}
+ private void updateDrawable(View thumbnailView, Bitmap bitmap) {
+ Drawable d = thumbnailView.getBackground();
+ if (d instanceof LayerDrawable) {
+ LayerDrawable layerD = (LayerDrawable) d;
+ Drawable thumb = layerD.findDrawableByLayerId(R.id.base_layer);
+ if (thumb != null) {
+ layerD.setDrawableByLayerId(R.id.base_layer,
+ new BitmapDrawable(getResources(), bitmap));
+ return;
+ }
+ }
+ Log.w(TAG, "Failed to update drawable");
+ }
+
public void show(boolean show, boolean animate) {
if (animate) {
if (mShowing != show) {
@@ -260,7 +292,7 @@ public class RecentsPanelView extends RelativeLayout
protected void onFinishInflate() {
super.onFinishInflate();
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mRecentsContainer = findViewById(R.id.recents_container);
+ mRecentsContainer = (ViewGroup) findViewById(R.id.recents_container);
mListAdapter = new ActivityDescriptionAdapter(mContext);
if (mRecentsContainer instanceof RecentsListView) {
RecentsListView listView = (RecentsListView) mRecentsContainer;
@@ -503,7 +535,35 @@ public class RecentsPanelView extends RelativeLayout
am.removeTask(ad.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
}
- public void handleLongPress(View selectedView) {
- // TODO show context menu : "Remove from list", "Show properties"
+ private void startApplicationDetailsActivity(String packageName) {
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
+ Uri.fromParts("package", packageName, null));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ getContext().startActivity(intent);
+ }
+
+ public void handleLongPress(final View selectedView, final View anchorView) {
+ PopupMenu popup = new PopupMenu(mContext, anchorView == null ? selectedView : anchorView);
+ popup.getMenuInflater().inflate(R.menu.recent_popup_menu, popup.getMenu());
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ if (item.getItemId() == R.id.recent_remove_item) {
+ mRecentsContainer.removeViewInLayout(selectedView);
+ } else if (item.getItemId() == R.id.recent_inspect_item) {
+ ViewHolder viewHolder = (ViewHolder) selectedView.getTag();
+ if (viewHolder != null) {
+ final ActivityDescription ad = viewHolder.activityDescription;
+ startApplicationDetailsActivity(ad.packageName);
+ mBar.animateCollapse();
+ } else {
+ throw new IllegalStateException("Oops, no tag on view " + selectedView);
+ }
+ } else {
+ return false;
+ }
+ return true;
+ }
+ });
+ popup.show();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 27bb0b5..9dd170c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -20,6 +20,7 @@ import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -42,8 +43,7 @@ import android.widget.ScrollView;
import com.android.systemui.R;
-public class RecentsVerticalScrollView extends ScrollView
- implements View.OnClickListener, View.OnTouchListener {
+public class RecentsVerticalScrollView extends ScrollView {
private static final String TAG = RecentsPanelView.TAG;
private static final boolean DEBUG_INVALIDATE = false;
private static final boolean DEBUG = RecentsPanelView.DEBUG;
@@ -57,6 +57,15 @@ public class RecentsVerticalScrollView extends ScrollView
private VelocityTracker mVelocityTracker;
private float mDensityScale;
private float mPagingTouchSlop;
+ private OnLongClickListener mOnLongClick = new OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ final View anchorView = v.findViewById(R.id.app_description);
+ mCurrentView = v;
+ mCallback.handleLongPress(v, anchorView);
+ mCurrentView = null; // make sure we don't accept the return click from this
+ return true;
+ }
+ };
public RecentsVerticalScrollView(Context context) {
this(context, null);
@@ -72,13 +81,12 @@ public class RecentsVerticalScrollView extends ScrollView
return mLinearLayout.getHeight() - getHeight();
}
- public void update() {
+ private void update() {
mLinearLayout.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
- View view = mAdapter.getView(i, null, mLinearLayout);
+ final View view = mAdapter.getView(i, null, mLinearLayout);
view.setClickable(true);
- view.setOnClickListener(this);
- view.setOnTouchListener(this);
+ view.setOnLongClickListener(mOnLongClick);
mLinearLayout.addView(view);
}
// Scroll to end after layout.
@@ -91,7 +99,20 @@ public class RecentsVerticalScrollView extends ScrollView
}
@Override
+ public void removeViewInLayout(final View view) {
+ ObjectAnimator anim = animateClosed(view, Constants.MAX_ESCAPE_ANIMATION_DURATION,
+ "x", view.getX(), view.getX() + view.getWidth());
+ anim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ RecentsVerticalScrollView.super.removeViewInLayout(view);
+ }
+ });
+ anim.start();
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
@@ -100,6 +121,18 @@ public class RecentsVerticalScrollView extends ScrollView
case MotionEvent.ACTION_DOWN:
mDragging = false;
mLastX = ev.getX();
+ final float x = ev.getX() + getScrollX();
+ final float y = ev.getY() + getScrollY();
+ mCurrentView = null;
+ for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
+ View item = mLinearLayout.getChildAt(i);
+ if (x >= item.getLeft() && x < item.getRight()
+ && y >= item.getTop() && y < item.getBottom()) {
+ mCurrentView = item;
+ Log.v(TAG, "Hit item " + item);
+ break;
+ }
+ }
break;
case MotionEvent.ACTION_MOVE:
@@ -111,6 +144,9 @@ public class RecentsVerticalScrollView extends ScrollView
break;
case MotionEvent.ACTION_UP:
+ if (mCurrentView != null) {
+ mCallback.handleOnClick(mCurrentView);
+ }
mDragging = false;
break;
}
@@ -125,7 +161,6 @@ public class RecentsVerticalScrollView extends ScrollView
} else if (view.getX() < thumbWidth* (1.0f - Constants.ALPHA_FADE_START)) {
result = 1.0f + (thumbWidth*Constants.ALPHA_FADE_START + view.getX()) / fadeWidth;
}
- if (DEBUG) Log.v(TAG, "FADE AMOUNT: " + result);
return result;
}
@@ -138,12 +173,12 @@ public class RecentsVerticalScrollView extends ScrollView
mVelocityTracker.addMovement(ev);
final View animView = mCurrentView;
- // TODO: Cache thumbnail
- final View thumb = animView.findViewById(R.id.app_thumbnail);
+
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
if (animView != null) {
final float delta = ev.getX() - mLastX;
+ final View thumb = animView.findViewById(R.id.app_thumbnail);
animView.setX(animView.getX() + delta);
animView.setAlpha(getAlphaForOffset(animView, thumb.getWidth()));
invalidateGlobalRegion(animView);
@@ -163,29 +198,11 @@ public class RecentsVerticalScrollView extends ScrollView
final float maxVelocity = Constants.ESCAPE_VELOCITY * mDensityScale;
if (Math.abs(velocityX) > Math.abs(velocityY)
&& Math.abs(velocityX) > maxVelocity
- && (velocityX > 0.0f) == (animView.getX() >= 0)) {
+ && (velocityX >= 0.0f) == (animView.getX() >= 0)) {
long duration =
(long) (Math.abs(newX-curX) * 1000.0f / Math.abs(velocityX));
duration = Math.min(duration, Constants.MAX_ESCAPE_ANIMATION_DURATION);
- anim = ObjectAnimator.ofFloat(animView, "x", curX, newX);
- anim.setInterpolator(new LinearInterpolator());
- final int swipeDirection = animView.getX() >= 0.0f ?
- RecentsCallback.SWIPE_RIGHT : RecentsCallback.SWIPE_LEFT;
- anim.addListener(new AnimatorListener() {
- public void onAnimationStart(Animator animation) {
- }
- public void onAnimationRepeat(Animator animation) {
- }
- public void onAnimationEnd(Animator animation) {
- mLinearLayout.removeView(mCurrentView);
- mCallback.handleSwipe(animView, swipeDirection);
- }
- public void onAnimationCancel(Animator animation) {
- mLinearLayout.removeView(mCurrentView);
- mCallback.handleSwipe(animView, swipeDirection);
- }
- });
- anim.setDuration(duration);
+ anim = animateClosed(animView, duration, "x", curX, newX);
} else { // Animate back to position
long duration = Math.abs(velocityX) > 0.0f ?
(long) (Math.abs(newX-curX) * 1000.0f / Math.abs(velocityX))
@@ -196,6 +213,7 @@ public class RecentsVerticalScrollView extends ScrollView
anim.setDuration(duration);
}
+ final View thumb = animView.findViewById(R.id.app_thumbnail);
anim.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
animView.setAlpha(getAlphaForOffset(animView, thumb.getWidth()));
@@ -212,6 +230,26 @@ public class RecentsVerticalScrollView extends ScrollView
return true;
}
+ private ObjectAnimator animateClosed(final View animView, long duration,
+ String attr, float from, float to) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(animView, attr, from, to);
+ anim.setInterpolator(new LinearInterpolator());
+ final int swipeDirection = animView.getX() >= 0.0f ?
+ RecentsCallback.SWIPE_RIGHT : RecentsCallback.SWIPE_LEFT;
+ anim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ mLinearLayout.removeView(animView);
+ mCallback.handleSwipe(animView, swipeDirection);
+ }
+ public void onAnimationCancel(Animator animation) {
+ mLinearLayout.removeView(animView);
+ mCallback.handleSwipe(animView, swipeDirection);
+ }
+ });
+ anim.setDuration(duration);
+ return anim;
+ }
+
void invalidateGlobalRegion(View view) {
RectF childBounds
= new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
@@ -236,13 +274,8 @@ public class RecentsVerticalScrollView extends ScrollView
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- LayoutInflater inflater = (LayoutInflater)
- mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
setScrollbarFadingEnabled(true);
-
mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout);
-
final int leftPadding = mContext.getResources()
.getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin);
setOverScrollEffectPadding(leftPadding, 0);
@@ -306,16 +339,7 @@ public class RecentsVerticalScrollView extends ScrollView
mLinearLayout.setLayoutTransition(transition);
}
- public void onClick(View view) {
- mCallback.handleOnClick(view);
- }
-
public void setCallback(RecentsCallback callback) {
mCallback = callback;
}
-
- public boolean onTouch(View v, MotionEvent event) {
- mCurrentView = v;
- return false;
- }
}