Merge "Double tap interaction for notifications on lockscreen." into master-lockscreen-dev

This commit is contained in:
Jorim Jaggi
2014-04-09 16:57:48 +00:00
committed by Android (Google) Code Review
13 changed files with 178 additions and 23 deletions

View File

@@ -16,6 +16,16 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/notification_quantum_press" />
<item android:state_pressed="false" android:drawable="@drawable/notification_quantum_background" />
<item android:state_pressed="true">
<shape>
<solid android:color="#ffd0d0d0" />
<corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
</shape>
</item>
<item>
<shape>
<solid android:color="#fffafafa" />
<corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
</shape>
</item>
</selector>

View File

@@ -15,7 +15,14 @@
~ limitations under the License
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff" />
<corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
</shape>
<touch-feedback
xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#ffffffff"
>
<item>
<shape>
<solid android:color="#f0d0d0d0" />
<corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
</shape>
</item>
</touch-feedback>

View File

@@ -17,7 +17,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:internal="http://schemas.android.com/apk/prv/res/android"
android:background="@android:drawable/notification_quantum_bg"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
android:layout_height="64dp"

View File

@@ -17,7 +17,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:internal="http://schemas.android.com/apk/prv/res/android"
android:background="@android:drawable/notification_quantum_bg"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -17,7 +17,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:internal="http://schemas.android.com/apk/prv/res/android"
android:background="@android:drawable/notification_quantum_bg"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@@ -16,7 +16,6 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:internal="http://schemas.android.com/apk/prv/res/android"
android:background="@android:drawable/notification_quantum_bg"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -18,7 +18,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:internal="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/status_bar_latest_event_content"
android:background="@android:drawable/notification_quantum_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
internal:layout_minHeight="65dp"

View File

@@ -1642,6 +1642,8 @@
<java-symbol type="layout" name="notification_template_quantum_inbox" />
<java-symbol type="color" name="notification_action_legacy_color_filter" />
<java-symbol type="drawable" name="notification_icon_legacy_bg_inset" />
<java-symbol type="drawable" name="notification_quantum_bg_dim" />
<java-symbol type="drawable" name="notification_quantum_bg" />
<!-- From SystemUI -->
<java-symbol type="anim" name="push_down_in" />

View File

@@ -32,6 +32,7 @@
android:layout_marginTop="@dimen/notification_divider_height"
android:focusable="true"
android:clickable="true"
android:background="@*android:drawable/notification_quantum_bg"
>
<com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded"

View File

@@ -435,8 +435,6 @@ public abstract class BaseStatusBar extends SystemUI implements
}
if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
} else {
content.setBackgroundResource(com.android.internal.R.drawable.notification_bg);
}
}
}
@@ -1004,7 +1002,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// Remove the expanded view.
ViewGroup rowParent = (ViewGroup)entry.row.getParent();
if (rowParent != null) rowParent.removeView(entry.row);
updateExpansionStates();
updateRowStates();
updateNotificationIcons();
return entry.notification;
@@ -1048,7 +1046,7 @@ public abstract class BaseStatusBar extends SystemUI implements
Log.d(TAG, "addNotificationViews: added at " + pos);
}
updateInterceptedState(entry);
updateExpansionStates();
updateRowStates();
updateNotificationIcons();
}
@@ -1056,7 +1054,10 @@ public abstract class BaseStatusBar extends SystemUI implements
addNotificationViews(createNotificationViews(key, notification));
}
protected void updateExpansionStates() {
/**
* Updates expanded, dimmed and locked states of notification rows.
*/
protected void updateRowStates() {
int n = mNotificationData.size();
for (int i = 0; i < n; i++) {
NotificationData.Entry entry = mNotificationData.get(i);
@@ -1068,6 +1069,8 @@ public abstract class BaseStatusBar extends SystemUI implements
entry.row.setExpanded(top || entry.row.isUserExpanded());
}
}
entry.row.setDimmed(mOnKeyguard);
entry.row.setLocked(mOnKeyguard);
}
}
@@ -1222,7 +1225,7 @@ public abstract class BaseStatusBar extends SystemUI implements
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
return;
}
updateExpansionStates();
updateRowStates();
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.

View File

@@ -36,10 +36,18 @@ public class ExpandableNotificationRow extends FrameLayout {
/** are we showing the "public" version */
private boolean mShowingPublic;
private LatestItemView mLatestItemView;
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mLatestItemView = (LatestItemView) findViewById(R.id.container);
}
public int getRowHeight() {
return mRowHeight;
}
@@ -93,4 +101,19 @@ public class ExpandableNotificationRow extends FrameLayout {
publicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
findViewById(R.id.expanded).setVisibility(show ? View.GONE : View.VISIBLE);
}
/**
* Sets the notification as dimmed, meaning that it will appear in a more gray variant.
*/
public void setDimmed(boolean dimmed) {
mLatestItemView.setDimmed(dimmed);
}
/**
* Sets the notification as locked. In the locked state, the first tap will produce a quantum
* ripple to make the notification brighter and only the second tap will cause a click.
*/
public void setLocked(boolean locked) {
mLatestItemView.setLocked(locked);
}
}

View File

@@ -17,16 +17,44 @@
package com.android.systemui.statusbar;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
public class LatestItemView extends FrameLayout {
private static final long DOUBLETAP_TIMEOUT_MS = 1000;
private boolean mDimmed;
private boolean mLocked;
/**
* Flag to indicate that the notification has been touched once and the second touch will
* click it.
*/
private boolean mActivated;
private float mDownX;
private float mDownY;
private final float mTouchSlop;
private boolean mHotspotActive;
public LatestItemView(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
private final Runnable mTapTimeoutRunnable = new Runnable() {
@Override
public void run() {
makeInactive();
}
};
@Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
@@ -45,4 +73,94 @@ public class LatestItemView extends FrameLayout {
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mLocked) {
return handleTouchEventLocked(event);
} else {
return super.onTouchEvent(event);
}
}
private boolean handleTouchEventLocked(MotionEvent event) {
int action = event.getActionMasked();
Drawable background = getBackground();
switch (action) {
case MotionEvent.ACTION_DOWN:
mDownX = event.getX();
mDownY = event.getY();
if (!mActivated) {
background.setHotspot(0, event.getX(), event.getY());
mHotspotActive = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (!isWithinTouchSlop(event)) {
makeInactive();
return false;
}
break;
case MotionEvent.ACTION_UP:
if (isWithinTouchSlop(event)) {
if (!mActivated) {
mActivated = true;
postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
} else {
performClick();
makeInactive();
}
} else {
makeInactive();
}
break;
case MotionEvent.ACTION_CANCEL:
makeInactive();
break;
default:
break;
}
return true;
}
/**
* Cancels the hotspot and makes the notification inactive.
*/
private void makeInactive() {
if (mHotspotActive) {
// Make sure that we clear the hotspot from the center.
getBackground().setHotspot(0, getWidth()/2, getHeight()/2);
getBackground().removeHotspot(0);
mHotspotActive = false;
}
mActivated = false;
removeCallbacks(mTapTimeoutRunnable);
}
private boolean isWithinTouchSlop(MotionEvent event) {
return Math.abs(event.getX() - mDownX) < mTouchSlop
&& Math.abs(event.getY() - mDownY) < mTouchSlop;
}
/**
* Sets the notification as dimmed, meaning that it will appear in a more gray variant.
*/
public void setDimmed(boolean dimmed) {
if (mDimmed != dimmed) {
mDimmed = dimmed;
if (dimmed) {
setBackgroundResource(com.android.internal.R.drawable.notification_quantum_bg_dim);
} else {
setBackgroundResource(com.android.internal.R.drawable.notification_quantum_bg);
}
}
}
/**
* Sets the notification as locked. In the locked state, the first tap will produce a quantum
* ripple to make the notification brighter and only the second tap will cause a click.
*/
public void setLocked(boolean locked) {
mLocked = locked;
}
}

View File

@@ -2804,9 +2804,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
mKeyguardSettingsFlipButton.setVisibility(View.VISIBLE);
mKeyguardSettingsFlipButton.findViewById(R.id.settings_button).setVisibility(View.VISIBLE);
mStackScroller.setAlpha(0.8f);
mStackScroller.setLayerType(View.LAYER_TYPE_HARDWARE, null);
updateExpansionStates();
updateRowStates();
}
public void hideKeyguard() {
@@ -2815,9 +2813,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mKeyguardStatusView.setVisibility(View.GONE);
mNotificationPanelHeader.setVisibility(View.VISIBLE);
mKeyguardSettingsFlipButton.setVisibility(View.GONE);
mStackScroller.setAlpha(1f);
mStackScroller.setLayerType(View.LAYER_TYPE_NONE, null);
updateExpansionStates();
updateRowStates();
}
public void userActivity() {