am d19697b5: Merge "New layout structure for the expanded status bar."

* commit 'd19697b58c260e566f7724c7de81cbfd50a931e1':
  New layout structure for the expanded status bar.
This commit is contained in:
Jorim Jaggi
2014-05-07 23:43:26 +00:00
committed by Android Git Automerger
23 changed files with 660 additions and 580 deletions

View File

@@ -25,7 +25,6 @@
android:id="@+id/content_holder"
android:layout_height="wrap_content"
android:layout_width="@dimen/notification_panel_width"
android:layout_marginStart="@dimen/notification_panel_margin_left"
android:background="@drawable/heads_up_window_bg"
/>
</com.android.systemui.statusbar.policy.HeadsUpNotificationView>

View File

@@ -22,5 +22,4 @@
android:layout_height="wrap_content"
android:background="#5f000000"
android:animateLayoutChanges="true"
android:visibility="gone"
android:columnCount="@integer/quick_settings_num_columns" />

View File

@@ -22,6 +22,5 @@
android:layout_height="wrap_content"
android:layout_width="@dimen/notification_panel_width"
android:id="@+id/content_holder"
android:layout_marginStart="@dimen/notification_panel_margin_left"
android:background="@drawable/notification_panel_bg"
/>

View File

@@ -23,9 +23,7 @@
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/notification_panel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="@dimen/notification_panel_padding_top"
android:layout_marginStart="@dimen/notification_panel_margin_left"
android:layout_height="match_parent"
>
<include
@@ -36,15 +34,6 @@
android:layout_gravity="bottom"
/>
<include
layout="@layout/status_bar_flip_button"
android:id="@+id/keyguard_flipper"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="right|top"
android:layout_marginTop="@dimen/status_bar_height"
android:visibility="gone" />
<com.android.keyguard.CarrierText
android:id="@+id/keyguard_carrier_text"
android:layout_width="wrap_content"
@@ -54,11 +43,6 @@
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium" />
<include layout="@layout/status_bar_expanded_header"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_panel_header_height"
/>
<include
layout="@layout/keyguard_status_view"
android:layout_height="wrap_content"
@@ -74,27 +58,54 @@
android:visibility="gone"
/>
<FrameLayout
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
android:id="@+id/notification_container_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/close_handle_underlap"
>
<include
layout="@layout/flip_settings"
android:layout_marginTop="@dimen/notification_panel_header_height"
android:clipToPadding="false"
android:clipChildren="false">
<com.android.systemui.statusbar.phone.ObservableScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
android:layout_height="match_parent"
android:visibility="invisible"
android:scrollbars="none"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="@layout/flip_settings"
android:layout_marginTop="@dimen/status_bar_header_height_expanded"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- A view to reserve space for the collapsed stack -->
<View
android:layout_height="@dimen/collapsed_stack_height"
android:layout_width="match_parent"/>
</LinearLayout>
</com.android.systemui.statusbar.phone.ObservableScrollView>
<com.android.systemui.statusbar.stack.NotificationStackScrollLayout
android:id="@+id/notification_stack_scroller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</FrameLayout>
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/close_handle_underlap"/>
</com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
<include layout="@layout/status_bar_expanded_header"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_header_height"
/>
<include
layout="@layout/keyguard_bottom_area"
android:visibility="gone" />
</com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->

View File

@@ -15,21 +15,30 @@
** limitations under the License.
-->
<LinearLayout
<!-- Extends RelativeLayout -->
<com.android.systemui.statusbar.phone.StatusBarHeaderView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_panel_header_height"
android:background="@drawable/notification_header_bg"
android:layout_height="@dimen/status_bar_header_height"
android:orientation="horizontal"
android:gravity="center_vertical"
android:baselineAligned="false"
>
<View
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/notification_header_bg"
android:clickable="true"
/>
<RelativeLayout
android:id="@+id/datetime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:background="@drawable/ic_notify_button_bg"
@@ -55,12 +64,6 @@
/>
</RelativeLayout>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
/>
<TextView
android:id="@+id/header_debug_info"
android:visibility="invisible"
@@ -74,18 +77,22 @@
android:padding="2dp"
/>
<include layout="@layout/status_bar_flip_button"
android:id="@+id/header_flipper"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"/>
<ImageView android:id="@+id/clear_all_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_toStartOf="@id/header_flipper"
android:scaleType="center"
android:src="@drawable/ic_notify_clear"
android:background="@drawable/ic_notify_button_bg"
android:contentDescription="@string/accessibility_clear_all"
/>
<include layout="@layout/status_bar_flip_button"
android:id="@+id/header_flipper"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="12dp" />
</LinearLayout>
</com.android.systemui.statusbar.phone.StatusBarHeaderView>

View File

@@ -15,22 +15,11 @@
~ limitations under the License
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="50dp"
android:layout_height="50dp">
<ImageView android:id="@+id/settings_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/ic_notify_settings"
android:background="@drawable/ic_notify_button_bg"
android:contentDescription="@string/accessibility_desc_quick_settings" />
<ImageView android:id="@+id/notification_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/ic_notifications"
android:background="@drawable/ic_notify_button_bg"
android:visibility="gone"
android:contentDescription="@string/accessibility_notifications_button" />
</FrameLayout>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/settings_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/ic_notify_quicksettings"
android:background="@drawable/ic_notify_button_bg"
android:contentDescription="@string/accessibility_desc_quick_settings"/>

View File

@@ -33,11 +33,10 @@
<com.android.systemui.statusbar.phone.PanelHolder
android:id="@+id/panel_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/panel_holder_padding_top">
android:layout_height="match_parent" >
<include layout="@layout/status_bar_expanded"
android:layout_width="@dimen/notification_panel_width"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start|top" />
</com.android.systemui.statusbar.phone.PanelHolder>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
* Copyright (c) 2012, 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.
*/
-->
<resources>
<!-- Layout parameters for the notification panel -->
<dimen name="notification_panel_margin_bottom">0dp</dimen>
<dimen name="notification_panel_margin_left">32dp</dimen>
</resources>

View File

@@ -19,10 +19,6 @@
<!-- The width of the notification panel window: 446 + 16 + 16 (padding in the bg drawable) -->
<dimen name="notification_panel_width">478dp</dimen>
<!-- Layout parameters for the notification panel -->
<dimen name="notification_panel_margin_bottom">192dp</dimen>
<dimen name="notification_panel_margin_left">16dp</dimen>
<!-- Gravity for the notification panel -->
<!-- 0x31 = top|center_horizontal -->
<integer name="notification_panel_layout_gravity">0x31</integer>
@@ -43,9 +39,6 @@
<dimen name="status_bar_recents_thumbnail_width">200dp</dimen>
<dimen name="status_bar_recents_thumbnail_height">177dp</dimen>
<!-- On tablets, panels drop from the statusbar instead of overlapping it. -->
<dimen name="panel_holder_padding_top">@*android:dimen/status_bar_height</dimen>
<!-- Minimum fraction of the screen that should be taken up by the notification panel. -->
<item type="dimen" name="notification_panel_min_height_frac">40%</item>

View File

@@ -24,8 +24,6 @@
<!-- The width of the ticker, including the icon -->
<dimen name="notification_ticker_width">360dp</dimen>
<!-- Status bar panel bottom offset (height of status bar - overlap) -->
<dimen name="status_bar_panel_bottom_offset">36dp</dimen>
<!-- gap on either side of status bar notification icons -->
<dimen name="status_bar_icon_padding">1dp</dimen>
<!-- The width of the notification panel window -->

View File

@@ -99,9 +99,6 @@
<integer name="blinds_pop_duration_ms">10</integer>
<!-- The device supports quick settings. -->
<bool name="config_hasQuickSettings">true</bool>
<!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
<bool name="config_show4GForLTE">true</bool>

View File

@@ -152,21 +152,11 @@
<!-- Amount of close_handle that will NOT overlap the notification list -->
<dimen name="close_handle_underlap">32dp</dimen>
<!-- Height of the notification panel header bar -->
<dimen name="notification_panel_header_height">48dp</dimen>
<!-- Height of the status bar header bar -->
<dimen name="status_bar_header_height">48dp</dimen>
<!-- Extra space above the panel -->
<dimen name="notification_panel_padding_top">0dp</dimen>
<!-- Extra space above the clock in the panel -->
<dimen name="notification_panel_header_padding_top">0dp</dimen>
<!-- Extra space above the panel holder -->
<dimen name="panel_holder_padding_top">0dp</dimen>
<!-- Layout parameters for the notification panel -->
<dimen name="notification_panel_margin_bottom">0dp</dimen>
<dimen name="notification_panel_margin_left">0dp</dimen>
<!-- Height of the status bar header bar when expanded -->
<dimen name="status_bar_header_height_expanded">144dp</dimen>
<!-- Gravity for the notification panel -->
<!-- 0x37 = fill_horizontal|top -->
@@ -261,6 +251,9 @@
<!-- The padding between the individual notification cards. -->
<dimen name="notification_padding">3dp</dimen>
<!-- The total height of the stack in its collapsed size (i.e. when quick settings is open) -->
<dimen name="collapsed_stack_height">94dp</dimen>
<!-- Width of the zen mode interstitial dialog. -->
<dimen name="zen_mode_dialog_width">320dp</dimen>

View File

@@ -1144,7 +1144,6 @@ public abstract class BaseStatusBar extends SystemUI implements
protected abstract void updateNotificationIcons();
protected abstract void tick(IBinder key, StatusBarNotification n, boolean firstTime);
protected abstract void updateExpandedViewPos(int expandedPosition);
protected abstract int getExpandedViewMaxHeight();
protected abstract boolean shouldDisableNavbarGestures();
protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {

View File

@@ -16,11 +16,17 @@
package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableView;
@@ -29,18 +35,40 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
public class NotificationPanelView extends PanelView implements
ExpandableView.OnHeightChangedListener {
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
View.OnClickListener {
public static final boolean DEBUG_GESTURES = true;
private static final int EXPANSION_ANIMATION_LENGTH = 375;
PhoneStatusBar mStatusBar;
private View mHeader;
private StatusBarHeaderView mHeader;
private QuickSettingsContainerView mQsContainer;
private View mKeyguardStatusView;
private ObservableScrollView mScrollView;
private View mStackScrollerContainer;
private NotificationStackScrollLayout mNotificationStackScroller;
private boolean mTrackingSettings;
private int mNotificationTopPadding;
private boolean mAnimateNextTopPaddingChange;
private Interpolator mExpansionInterpolator;
private int mTrackingPointer;
private VelocityTracker mVelocityTracker;
private boolean mTracking;
private boolean mQsExpanded;
private float mInitialHeightOnTouch;
private float mInitialTouchX;
private float mInitialTouchY;
private float mQsExpansionHeight;
private int mQsMinExpansionHeight;
private int mQsMaxExpansionHeight;
private int mMinStackHeight;
private float mNotificationTranslation;
private int mStackScrollerIntrinsicPadding;
private boolean mQsExpansionEnabled = true;
private ValueAnimator mQsExpansionAnimator;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -63,14 +91,21 @@ public class NotificationPanelView extends PanelView implements
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mHeader = findViewById(R.id.header);
mHeader = (StatusBarHeaderView) findViewById(R.id.header);
mHeader.getBackgroundView().setOnClickListener(this);
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
mStackScrollerContainer = findViewById(R.id.notification_container_parent);
mQsContainer = (QuickSettingsContainerView) findViewById(R.id.quick_settings_container);
mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
mScrollView.setListener(this);
mNotificationStackScroller = (NotificationStackScrollLayout)
findViewById(R.id.notification_stack_scroller);
mNotificationStackScroller.setOnHeightChangedListener(this);
mNotificationTopPadding = getResources().getDimensionPixelSize(
R.dimen.notifications_top_padding);
mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height);
mExpansionInterpolator = AnimationUtils.loadInterpolator(
getContext(), android.R.interpolator.fast_out_slow_in);
}
@Override
@@ -78,11 +113,21 @@ public class NotificationPanelView extends PanelView implements
super.onLayout(changed, left, top, right, bottom);
int keyguardBottomMargin =
((MarginLayoutParams) mKeyguardStatusView.getLayoutParams()).bottomMargin;
mNotificationStackScroller.setTopPadding(mStatusBar.getBarState() == StatusBarState.KEYGUARD
? mKeyguardStatusView.getBottom() + keyguardBottomMargin
: mHeader.getBottom() + mNotificationTopPadding,
mAnimateNextTopPaddingChange);
mAnimateNextTopPaddingChange = false;
if (!mQsExpanded) {
mStackScrollerIntrinsicPadding = mStatusBar.getBarState() == StatusBarState.KEYGUARD
? mKeyguardStatusView.getBottom() + keyguardBottomMargin
: mHeader.getBottom() + mNotificationTopPadding;
mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding,
mAnimateNextTopPaddingChange);
mAnimateNextTopPaddingChange = false;
}
// Calculate quick setting heights.
mQsMinExpansionHeight = mHeader.getCollapsedHeight();
mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight();
if (mQsExpansionHeight == 0) {
mQsExpansionHeight = mQsMinExpansionHeight;
}
}
public void animateNextTopPaddingChange() {
@@ -90,6 +135,30 @@ public class NotificationPanelView extends PanelView implements
requestLayout();
}
/**
* @return Whether Quick Settings are currently expanded.
*/
public boolean isQsExpanded() {
return mQsExpanded;
}
public void setQsExpansionEnabled(boolean qsExpansionEnabled) {
mQsExpansionEnabled = qsExpansionEnabled;
mHeader.setExpansionEnabled(qsExpansionEnabled);
}
public void closeQs() {
cancelAnimation();
setQsExpansion(mQsMinExpansionHeight);
}
public void openQs() {
cancelAnimation();
if (mQsExpansionEnabled) {
setQsExpansion(mQsMaxExpansionHeight);
}
}
@Override
public void fling(float vel, boolean always) {
GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
@@ -114,42 +183,245 @@ public class NotificationPanelView extends PanelView implements
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// intercept for quick settings
if (event.getAction() == MotionEvent.ACTION_DOWN) {
final View target = mStatusBar.getBarState() == StatusBarState.KEYGUARD
? mKeyguardStatusView
: mHeader;
final boolean inTarget = PhoneStatusBar.inBounds(target, event, true);
if (inTarget && !isInSettings()) {
mTrackingSettings = true;
requestDisallowInterceptTouchEvent(true);
return true;
}
if (!inTarget && isInSettings()) {
mTrackingSettings = true;
requestDisallowInterceptTouchEvent(true);
return true;
}
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
mTrackingPointer = event.getPointerId(pointerIndex);
}
return super.onInterceptTouchEvent(event);
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mInitialTouchY = y;
mInitialTouchX = x;
initVelocityTracker();
trackMovement(event);
if (shouldIntercept(mInitialTouchX, mInitialTouchY, 0)) {
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_POINTER_UP:
final int upPointer = event.getPointerId(event.getActionIndex());
if (mTrackingPointer == upPointer) {
// gesture is ongoing, find a new pointer to track
final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
mTrackingPointer = event.getPointerId(newIndex);
mInitialTouchX = event.getX(newIndex);
mInitialTouchY = event.getY(newIndex);
}
break;
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
trackMovement(event);
if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)
&& shouldIntercept(mInitialTouchX, mInitialTouchY, h)) {
onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
mInitialTouchY = y;
mInitialTouchX = x;
mTracking = true;
return true;
}
break;
}
return !mQsExpanded && super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
// implementation.
if (mTrackingSettings) {
mStatusBar.onSettingsEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL) {
mTrackingSettings = false;
if (mTracking) {
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
mTrackingPointer = event.getPointerId(pointerIndex);
}
final float y = event.getY(pointerIndex);
final float x = event.getX(pointerIndex);
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mTracking = true;
mInitialTouchY = y;
mInitialTouchX = x;
onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
initVelocityTracker();
trackMovement(event);
break;
case MotionEvent.ACTION_POINTER_UP:
final int upPointer = event.getPointerId(event.getActionIndex());
if (mTrackingPointer == upPointer) {
// gesture is ongoing, find a new pointer to track
final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
final float newY = event.getY(newIndex);
final float newX = event.getX(newIndex);
mTrackingPointer = event.getPointerId(newIndex);
mInitialHeightOnTouch = mQsExpansionHeight;
mInitialTouchY = newY;
mInitialTouchX = newX;
}
break;
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
setQsExpansion(h + mInitialHeightOnTouch);
trackMovement(event);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mTracking = false;
mTrackingPointer = -1;
trackMovement(event);
float vel = getCurrentVelocity();
// TODO: Better logic whether we should expand or not.
flingSettings(vel, vel > 0);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
return true;
}
if (isInSettings()) {
return true;
// Consume touch events when QS are expanded.
return mQsExpanded || super.onTouchEvent(event);
}
private void onQsExpansionStarted() {
cancelAnimation();
// Reset scroll position and apply that position to the expanded height.
float height = mQsExpansionHeight - mScrollView.getScrollY();
mScrollView.scrollTo(0, 0);
setQsExpansion(height);
}
private void expandQs() {
mHeader.setExpanded(true);
mNotificationStackScroller.setEnabled(false);
mScrollView.setVisibility(View.VISIBLE);
mQsExpanded = true;
}
private void collapseQs() {
mHeader.setExpanded(false);
mNotificationStackScroller.setEnabled(true);
mScrollView.setVisibility(View.INVISIBLE);
mQsExpanded = false;
}
private void setQsExpansion(float height) {
height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight);
if (height > mQsMinExpansionHeight && !mQsExpanded) {
expandQs();
} else if (height <= mQsMinExpansionHeight && mQsExpanded) {
collapseQs();
}
mQsExpansionHeight = height;
mHeader.setExpansion(height);
setQsTranslation(height);
setQsStackScrollerPadding(height);
}
private void setQsTranslation(float height) {
mQsContainer.setY(height - mQsContainer.getHeight());
}
private void setQsStackScrollerPadding(float height) {
float start = height - mScrollView.getScrollY() + mNotificationTopPadding;
float stackHeight = mNotificationStackScroller.getHeight() - start;
if (stackHeight <= mMinStackHeight) {
float overflow = mMinStackHeight - stackHeight;
stackHeight = mMinStackHeight;
start = mNotificationStackScroller.getHeight() - stackHeight;
mNotificationStackScroller.setTranslationY(overflow);
mNotificationTranslation = overflow + mScrollView.getScrollY();
} else {
mNotificationStackScroller.setTranslationY(0);
mNotificationTranslation = mScrollView.getScrollY();
}
mNotificationStackScroller.setTopPadding(clampQsStackScrollerPadding((int) start), false);
}
private int clampQsStackScrollerPadding(int desiredPadding) {
return Math.max(desiredPadding, mStackScrollerIntrinsicPadding);
}
private void trackMovement(MotionEvent event) {
if (mVelocityTracker != null) mVelocityTracker.addMovement(event);
}
private void initVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
}
mVelocityTracker = VelocityTracker.obtain();
}
private float getCurrentVelocity() {
if (mVelocityTracker == null) {
return 0;
}
mVelocityTracker.computeCurrentVelocity(1000);
return mVelocityTracker.getYVelocity();
}
private void cancelAnimation() {
if (mQsExpansionAnimator != null) {
mQsExpansionAnimator.cancel();
}
}
private void flingSettings(float vel, boolean expand) {
// TODO: Actually use velocity.
float target = expand ? mQsMaxExpansionHeight : mQsMinExpansionHeight;
ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
animator.setDuration(EXPANSION_ANIMATION_LENGTH);
animator.setInterpolator(mExpansionInterpolator);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setQsExpansion((Float) animation.getAnimatedValue());
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mQsExpansionAnimator = null;
}
});
animator.start();
mQsExpansionAnimator = animator;
}
/**
* @return Whether we should intercept a gesture to open Quick Settings.
*/
private boolean shouldIntercept(float x, float y, float yDiff) {
if (!mQsExpansionEnabled) {
return false;
}
View headerView = mStatusBar.getBarState() == StatusBarState.KEYGUARD && !mQsExpanded
? mKeyguardStatusView
: mHeader;
boolean onHeader = x >= headerView.getLeft() && x <= headerView.getRight()
&& y >= headerView.getTop() && y <= headerView.getBottom();
if (mQsExpanded) {
return onHeader || (mScrollView.isScrolledToBottom() && yDiff < 0);
} else {
return onHeader;
}
return super.onTouchEvent(event);
}
@Override
@@ -164,14 +436,16 @@ public class NotificationPanelView extends PanelView implements
protected int getMaxPanelHeight() {
if (!isInSettings()) {
int maxPanelHeight = super.getMaxPanelHeight();
int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin();
int notificationMarginBottom = mStackScrollerContainer.getPaddingBottom();
int emptyBottomMargin = notificationMarginBottom
+ mNotificationStackScroller.getEmptyBottomMargin();
return maxPanelHeight - emptyBottomMargin;
}
return super.getMaxPanelHeight();
}
private boolean isInSettings() {
return mStatusBar != null && mStatusBar.isFlippedToSettings();
return mQsExpanded;
}
@Override
@@ -200,4 +474,24 @@ public class NotificationPanelView extends PanelView implements
public void onHeightChanged(ExpandableView view) {
requestPanelHeightUpdate();
}
@Override
public void onScrollChanged() {
if (mQsExpanded) {
mNotificationStackScroller.setTranslationY(
mNotificationTranslation - mScrollView.getScrollY());
}
}
@Override
public void onClick(View v) {
if (v == mHeader.getBackgroundView()) {
onQsExpansionStarted();
if (mQsExpanded) {
flingSettings(0 /* vel */, false /* expand */);
} else if (mQsExpansionEnabled) {
flingSettings(0 /* vel */, true /* expand */);
}
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2014 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
*/
package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/**
* The container with notification stack scroller and quick settings inside.
*/
public class NotificationsQuickSettingsContainer extends FrameLayout {
public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean fitSystemWindows(Rect insets) {
setPadding(0, 0, 0, insets.bottom);
insets.bottom = 0;
return true;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2014 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
*/
package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ScrollView;
/**
* A scroll view which can be observed for scroll change events.
*/
public class ObservableScrollView extends ScrollView {
private Listener mListener;
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setListener(Listener listener) {
mListener = listener;
}
public boolean isScrolledToBottom() {
return getScrollY() == getMaxScrollY();
}
private int getMaxScrollY() {
int scrollRange = 0;
if (getChildCount() > 0) {
View child = getChildAt(0);
scrollRange = Math.max(0,
child.getHeight() - (getHeight() - mPaddingBottom - mPaddingTop));
}
return scrollRange;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mListener != null) {
mListener.onScrollChanged();
}
}
public interface Listener {
void onScrollChanged();
}
}

View File

@@ -75,7 +75,7 @@ public class PanelView extends FrameLayout {
private boolean mClosing;
private boolean mTracking;
private int mTrackingPointer;
private int mTouchSlop;
protected int mTouchSlop;
private TimeAnimator mTimeAnimator;
private ObjectAnimator mPeekAnimator;
@@ -220,9 +220,9 @@ public class PanelView extends FrameLayout {
private float mVel, mAccel;
protected int mMaxPanelHeight = 0;
private String mViewName;
protected float mInitialTouchY;
protected float mInitialTouchX;
protected float mFinalTouchY;
private float mInitialTouchY;
private float mInitialTouchX;
private float mFinalTouchY;
protected void onExpandingFinished() {
}

View File

@@ -73,7 +73,6 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator;
@@ -192,8 +191,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
int mIconHPadding = -1;
Display mDisplay;
Point mCurrentDisplaySize = new Point();
private float mHeadsUpVerticalOffset;
private int[] mStackScrollerPosition = new int[2];
StatusBarWindowView mStatusBarWindow;
PhoneStatusBarView mStatusBarView;
@@ -222,14 +219,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
View mExpandedContents;
int mNotificationPanelGravity;
int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
int mNotificationPanelMarginBottomPx;
float mNotificationPanelMinHeightFrac;
boolean mNotificationPanelIsFullScreenWidth;
TextView mNotificationPanelDebugText;
// settings
QuickSettings mQS;
boolean mHasQuickSettings;
View mFlipSettingsView;
QuickSettingsContainerView mSettingsContainer;
@@ -245,14 +241,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
int mKeyguardMaxNotificationCount;
View mDateTimeView;
View mClearButton;
FlipperButton mHeaderFlipper, mKeyguardFlipper;
ImageView mHeaderFlipper;
// carrier/wifi label
private TextView mCarrierLabel;
private boolean mCarrierLabelVisible = false;
private int mCarrierLabelHeight;
private TextView mEmergencyCallLabel;
private int mNotificationHeaderHeight;
private int mStatusBarHeaderHeight;
private View mKeyguardCarrierLabel;
private boolean mShowCarrierInPanel = false;
@@ -326,11 +322,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
"selfChange=%s userSetup=%s mUserSetup=%s",
selfChange, userSetup, mUserSetup));
mHeaderFlipper.userSetup(userSetup);
mKeyguardFlipper.userSetup(userSetup);
if (userSetup != mUserSetup) {
mUserSetup = userSetup;
if (mNotificationPanel != null) {
mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned() && userSetup);
}
if (!mUserSetup && mStatusBarView != null)
animateCollapseQuickSettings();
}
@@ -651,16 +648,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mClearButton.setEnabled(false);
mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
mHasQuickSettings = res.getBoolean(R.bool.config_hasQuickSettings);
mDateTimeView = mNotificationPanelHeader.findViewById(R.id.datetime);
if (mDateTimeView != null) {
mDateTimeView.setOnClickListener(mClockClickListener);
mDateTimeView.setEnabled(true);
}
mHeaderFlipper = new FlipperButton(mStatusBarWindow.findViewById(R.id.header_flipper));
mKeyguardFlipper =new FlipperButton(mStatusBarWindow.findViewById(R.id.keyguard_flipper));
mHeaderFlipper = (ImageView) mStatusBarWindow.findViewById(R.id.header_flipper);
if (!mNotificationPanelIsFullScreenWidth) {
mNotificationPanel.setSystemUiVisibility(
@@ -735,26 +729,23 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// updateCarrierLabelVisibility(false);
}
// Quick Settings (where available, some restrictions apply)
if (mHasQuickSettings) {
// Quick Settings needs a container to survive
mSettingsContainer = (QuickSettingsContainerView)
mStatusBarWindow.findViewById(R.id.quick_settings_container);
mFlipSettingsView = mSettingsContainer;
if (mSettingsContainer != null) {
mQS = new QuickSettings(mContext, mSettingsContainer);
if (!mNotificationPanelIsFullScreenWidth) {
mSettingsContainer.setSystemUiVisibility(
View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS
| View.STATUS_BAR_DISABLE_SYSTEM_INFO);
}
mQS.setService(this);
mQS.setBar(mStatusBarView);
mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
mLocationController, mRotationLockController);
} else {
mQS = null; // fly away, be free
// Quick Settings needs a container to survive
mSettingsContainer = (QuickSettingsContainerView)
mStatusBarWindow.findViewById(R.id.quick_settings_container);
mFlipSettingsView = mSettingsContainer;
if (mSettingsContainer != null) {
mQS = new QuickSettings(mContext, mSettingsContainer);
if (!mNotificationPanelIsFullScreenWidth) {
mSettingsContainer.setSystemUiVisibility(
View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS
| View.STATUS_BAR_DISABLE_SYSTEM_INFO);
}
mQS.setService(this);
mQS.setBar(mStatusBarView);
mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
mLocationController, mRotationLockController);
} else {
mQS = null; // fly away, be free
}
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -775,101 +766,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mStatusBarView;
}
public boolean onSettingsEvent(MotionEvent event) {
userActivity();
if (mSettingsClosing
&& mFlipSettingsViewAnim != null && mFlipSettingsViewAnim.isRunning()) {
return true;
}
if (mSettingsTracker != null) {
mSettingsTracker.addMovement(event);
}
final int slop = ViewConfiguration.get(mContext).getScaledTouchSlop();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mSettingsTracker = VelocityTracker.obtain();
mSettingsDownY = event.getY();
mSettingsCancelled = false;
mSettingsStarted = false;
mSettingsClosing = mFlipSettingsView.getVisibility() == View.VISIBLE;
if (mSettingsClosing) {
mStackScroller.setVisibility(View.VISIBLE);
} else {
mFlipSettingsView.setTranslationY(-mNotificationPanel.getMeasuredHeight());
}
dispatchSettingsEvent(event);
} else if (mSettingsTracker != null && (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL)) {
final float dy = event.getY() - mSettingsDownY;
final FlipperButton flipper = mState == StatusBarState.KEYGUARD
? mKeyguardFlipper
: mHeaderFlipper;
final boolean inButton = flipper.inHolderBounds(event);
final boolean qsTap = mSettingsClosing && Math.abs(dy) < slop;
if (!qsTap && !inButton) {
mSettingsTracker.computeCurrentVelocity(1000);
final float vy = mSettingsTracker.getYVelocity();
final boolean animate = true;
if (dy <= slop || vy <= 0) {
flipToNotifications(animate);
} else {
flipToSettings(animate);
}
}
mSettingsTracker.recycle();
mSettingsTracker = null;
dispatchSettingsEvent(event);
} else if (mSettingsTracker != null && event.getAction() == MotionEvent.ACTION_MOVE) {
final float dy = event.getY() - mSettingsDownY;
if (mSettingsClosing) {
positionSettings(dy);
final boolean qsTap = Math.abs(dy) < slop;
if (!mSettingsCancelled && !qsTap) {
MotionEvent cancelEvent = MotionEvent.obtainNoHistory(event);
cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
dispatchSettingsEvent(cancelEvent);
mSettingsCancelled = true;
}
} else {
if (!mSettingsStarted && dy > slop) {
mSettingsStarted = true;
mFlipSettingsView.setVisibility(View.VISIBLE);
mStackScroller.setVisibility(View.VISIBLE);
}
if (mSettingsStarted) {
positionSettings(dy);
}
dispatchSettingsEvent(event);
}
}
return true;
}
private void dispatchSettingsEvent(MotionEvent event) {
final View target = mSettingsClosing ? mFlipSettingsView : mNotificationPanelHeader;
final int[] targetLoc = new int[2];
target.getLocationInWindow(targetLoc);
final int[] panelLoc = new int[2];
mNotificationPanel.getLocationInWindow(panelLoc);
final int dx = targetLoc[0] - panelLoc[0];
final int dy = targetLoc[1] - panelLoc[1];
event.offsetLocation(-dx, -dy);
target.dispatchTouchEvent(event);
}
private void positionSettings(float dy) {
if (mSettingsClosing) {
final int ph = mNotificationPanel.getMeasuredHeight();
dy = Math.min(Math.max(-ph, dy), 0);
mFlipSettingsView.setTranslationY(dy);
mStackScroller.setTranslationY(ph + dy);
} else {
final int h = mFlipSettingsView.getBottom();
dy = Math.min(Math.max(0, dy), h);
mFlipSettingsView.setTranslationY(-h + dy);
mStackScroller.setTranslationY(dy);
}
}
private void startKeyguard() {
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
@@ -1230,8 +1126,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
((ImageView)mClearButton).setImageResource(R.drawable.ic_notify_clear);
}
mHeaderFlipper.refreshLayout();
mKeyguardFlipper.refreshLayout();
if (mHeaderFlipper != null) {
// Force asset reloading
mHeaderFlipper.setImageDrawable(null);
mHeaderFlipper.setImageResource(R.drawable.ic_notify_quicksettings);
}
refreshAllStatusBarIcons();
}
@@ -1286,8 +1185,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
mHeaderFlipper.provisionCheck(provisioned);
mKeyguardFlipper.provisionCheck(provisioned);
mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup);
}
@Override
@@ -1362,7 +1260,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final boolean makeVisible =
!(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
&& mStackScroller.getHeight() < (mNotificationPanel.getHeight()
- mCarrierLabelHeight - mNotificationHeaderHeight)
- mCarrierLabelHeight - mStatusBarHeaderHeight)
&& mStackScroller.getVisibility() == View.VISIBLE
&& mState != StatusBarState.KEYGUARD;
@@ -1775,47 +1673,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
public void flipToNotifications(boolean animate) {
cancelAnim(mFlipSettingsViewAnim);
cancelAnim(mScrollViewAnim);
cancelAnim(mClearButtonAnim);
mHeaderFlipper.cancel();
mKeyguardFlipper.cancel();
mStackScroller.setVisibility(View.VISIBLE);
final int h = mNotificationPanel.getMeasuredHeight();
if (animate) {
final float settingsY =
mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : 0;
final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : h;
mScrollViewAnim = start(
interpolator(mDecelerateInterpolator,
ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, 0)
.setDuration(FLIP_DURATION)
));
mFlipSettingsViewAnim = start(
setVisibilityWhenDone(
interpolator(mDecelerateInterpolator,
ObjectAnimator.ofFloat(
mFlipSettingsView, View.TRANSLATION_Y, settingsY, -h))
.setDuration(FLIP_DURATION),
mFlipSettingsView, View.INVISIBLE));
} else {
mStackScroller.setTranslationY(0);
mFlipSettingsView.setTranslationY(-h);
mFlipSettingsView.setVisibility(View.INVISIBLE);
}
mHeaderFlipper.flipToNotifications(animate);
mKeyguardFlipper.flipToNotifications(animate);
mClearButton.setVisibility(View.VISIBLE);
mClearButton.setAlpha(0f);
setAreThereNotifications(); // this will show/hide the button as necessary
mNotificationPanel.postDelayed(new Runnable() {
public void run() {
updateCarrierLabelVisibility(false);
}
}, animate ? FLIP_DURATION - 150 : 0);
if (mOnFlipRunnable != null) {
mOnFlipRunnable.run();
}
// TODO: Animation
mNotificationPanel.closeQs();
}
@Override
@@ -1829,78 +1688,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (!mUserSetup) return;
mNotificationPanel.expand();
if (mFlipSettingsView.getVisibility() != View.VISIBLE
|| mFlipSettingsView.getTranslationY() < 0) {
flipToSettings(true /*animate*/);
}
mNotificationPanel.openQs();
if (false) postStartTracing();
}
public boolean isFlippedToSettings() {
if (mFlipSettingsView != null) {
return mFlipSettingsView.getVisibility() == View.VISIBLE;
if (mNotificationPanel != null) {
return mNotificationPanel.isQsExpanded();
}
return false;
}
public void flipToSettings(boolean animate) {
// Settings are not available in setup
if (!mUserSetup) return;
cancelAnim(mFlipSettingsViewAnim);
cancelAnim(mScrollViewAnim);
mHeaderFlipper.cancel();
mKeyguardFlipper.cancel();
cancelAnim(mClearButtonAnim);
mFlipSettingsView.setVisibility(View.VISIBLE);
final int h = mNotificationPanel.getMeasuredHeight();
if (animate) {
final float settingsY
= mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : -h;
final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : 0;
mFlipSettingsViewAnim = start(
startDelay(0,
interpolator(mDecelerateInterpolator,
ObjectAnimator.ofFloat(mFlipSettingsView, View.TRANSLATION_Y,
settingsY, 0f)
.setDuration(FLIP_DURATION)
)));
mScrollViewAnim = start(
setVisibilityWhenDone(
interpolator(mDecelerateInterpolator,
ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, h)
)
.setDuration(FLIP_DURATION),
mStackScroller, View.INVISIBLE));
} else {
mFlipSettingsView.setTranslationY(0);
mStackScroller.setTranslationY(h);
mStackScroller.setVisibility(View.INVISIBLE);
}
mHeaderFlipper.flipToSettings(animate);
mKeyguardFlipper.flipToSettings(animate);
if (animate) {
mClearButtonAnim = start(
setVisibilityWhenDone(
ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
.setDuration(FLIP_DURATION),
mClearButton, View.INVISIBLE));
} else {
mClearButton.setAlpha(0);
mClearButton.setVisibility(View.INVISIBLE);
}
mNotificationPanel.postDelayed(new Runnable() {
public void run() {
updateCarrierLabelVisibility(false);
}
}, animate ? FLIP_DURATION - 150 : 0);
if (mOnFlipRunnable != null) {
mOnFlipRunnable.run();
}
}
public void animateCollapseQuickSettings() {
mStatusBarView.collapseAllPanels(true);
}
@@ -1927,12 +1726,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mStackScroller.setVisibility(View.VISIBLE);
mNotificationPanel.setVisibility(View.GONE);
mFlipSettingsView.setVisibility(View.GONE);
setAreThereNotifications(); // show the clear button
mHeaderFlipper.reset();
mKeyguardFlipper.reset();
mNotificationPanel.closeQs();
mExpandedVisible = false;
if (mNavigationBarView != null)
@@ -2463,19 +2260,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
void updateExpandedInvisiblePosition() {
mTrackingPosition = -mDisplayMetrics.heightPixels;
}
static final float saturate(float a) {
return a < 0f ? 0f : (a > 1f ? 1f : a);
}
@Override
protected int getExpandedViewMaxHeight() {
return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
}
@Override
public void updateExpandedViewPos(int thingy) {
if (SPEW) Log.v(TAG, "updateExpandedViewPos");
@@ -2486,15 +2274,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
lp.gravity = mNotificationPanelGravity;
lp.setMarginStart(mNotificationPanelMarginPx);
mNotificationPanel.setLayoutParams(lp);
if (ENABLE_HEADS_UP && mHeadsUpNotificationView != null) {
mHeadsUpNotificationView.setMargin(mNotificationPanelMarginPx);
mStackScroller.getLocationOnScreen(mStackScrollerPosition);
mHeadsUpVerticalOffset = mStackScrollerPosition[1] - mNaturalBarHeight;
}
updateCarrierLabelVisibility(false);
}
@@ -2542,17 +2323,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
animateCollapsePanels();
}
private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
public void onClick(View v) {
if (mHasQuickSettings) {
animateExpandSettingsPanel();
} else {
startActivityDismissingKeyguard(
new Intent(android.provider.Settings.ACTION_SETTINGS), true);
}
}
};
private View.OnClickListener mClockClickListener = new View.OnClickListener() {
public void onClick(View v) {
startActivityDismissingKeyguard(
@@ -2653,17 +2423,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
public void animateHeadsUp(boolean animateInto, float frac) {
if (!ENABLE_HEADS_UP || mHeadsUpNotificationView == null) return;
frac = frac / 0.4f;
frac = frac < 1.0f ? frac : 1.0f;
float alpha = 1.0f - frac;
float offset = mHeadsUpVerticalOffset * frac;
offset = animateInto ? offset : 0f;
mHeadsUpNotificationView.setAlpha(alpha);
mHeadsUpNotificationView.setY(offset);
}
public void onHeadsUpDismissed() {
if (mInterruptingNotificationEntry == null) return;
mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
@@ -2736,17 +2495,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
mNotificationPanelMarginBottomPx
= (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
mNotificationPanelMarginPx
= (int) res.getDimension(R.dimen.notification_panel_margin_left);
mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
if (mNotificationPanelGravity <= 0) {
mNotificationPanelGravity = Gravity.START | Gravity.TOP;
}
mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
mStatusBarHeaderHeight = res.getDimensionPixelSize(R.dimen.status_bar_header_height);
mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
@@ -3016,9 +2771,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void updateKeyguardState() {
if (mState == StatusBarState.KEYGUARD) {
if (isFlippedToSettings()) {
flipToNotifications(false /*animate*/);
}
mKeyguardStatusView.setVisibility(View.VISIBLE);
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.setVisibility(View.VISIBLE);
@@ -3026,7 +2778,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mKeyguardCarrierLabel.setVisibility(View.VISIBLE);
mNotificationPanelHeader.setVisibility(View.GONE);
mKeyguardFlipper.setVisibility(View.VISIBLE);
mNotificationPanel.closeQs();
mSettingsContainer.setKeyguardShowing(true);
} else {
mKeyguardStatusView.setVisibility(View.GONE);
@@ -3035,7 +2787,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mKeyguardCarrierLabel.setVisibility(View.GONE);
mNotificationPanelHeader.setVisibility(View.VISIBLE);
mKeyguardFlipper.setVisibility(View.GONE);
mSettingsContainer.setKeyguardShowing(false);
}
@@ -3202,131 +2953,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
* @return a ViewGroup that spans the entire panel which contains the quick settings
*/
public ViewGroup getQuickSettingsOverlayParent() {
if (mHasQuickSettings) {
return mNotificationPanel;
} else {
return null;
}
}
public static boolean inBounds(View view, MotionEvent event, boolean orAbove) {
final int[] location = new int[2];
view.getLocationInWindow(location);
final int rx = (int) event.getRawX();
final int ry = (int) event.getRawY();
return rx >= location[0] && rx <= location[0] + view.getMeasuredWidth()
&& (orAbove || ry >= location[1]) && ry <= location[1] + view.getMeasuredHeight();
}
private final class FlipperButton {
private final View mHolder;
private ImageView mSettingsButton, mNotificationButton;
private Animator mSettingsButtonAnim, mNotificationButtonAnim;
public FlipperButton(View holder) {
mHolder = holder;
mSettingsButton = (ImageView) holder.findViewById(R.id.settings_button);
if (mSettingsButton != null) {
mSettingsButton.setOnClickListener(mSettingsButtonListener);
if (mHasQuickSettings) {
// the settings panel is hiding behind this button
mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
mSettingsButton.setVisibility(View.VISIBLE);
} else {
// no settings panel, go straight to settings
mSettingsButton.setVisibility(View.VISIBLE);
mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
}
}
mNotificationButton = (ImageView) holder.findViewById(R.id.notification_button);
if (mNotificationButton != null) {
mNotificationButton.setOnClickListener(mNotificationButtonListener);
}
}
public boolean inHolderBounds(MotionEvent event) {
return inBounds(mHolder, event, false);
}
public void provisionCheck(boolean provisioned) {
if (mSettingsButton != null) {
mSettingsButton.setEnabled(provisioned);
}
}
public void userSetup(boolean userSetup) {
if (mSettingsButton != null) {
mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
}
}
public void reset() {
cancel();
mSettingsButton.setVisibility(View.VISIBLE);
mNotificationButton.setVisibility(View.GONE);
}
public void refreshLayout() {
if (mSettingsButton != null) {
// Force asset reloading
mSettingsButton.setImageDrawable(null);
mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
}
if (mNotificationButton != null) {
// Force asset reloading
mNotificationButton.setImageDrawable(null);
mNotificationButton.setImageResource(R.drawable.ic_notifications);
}
}
public void flipToSettings(boolean animate) {
mNotificationButton.setVisibility(View.VISIBLE);
if (animate) {
mSettingsButtonAnim = start(
setVisibilityWhenDone(
ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
.setDuration(FLIP_DURATION_OUT),
mStackScroller, View.INVISIBLE));
mNotificationButtonAnim = start(
startDelay(FLIP_DURATION_OUT,
ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
.setDuration(FLIP_DURATION_IN)));
} else {
mSettingsButton.setAlpha(0f);
mSettingsButton.setVisibility(View.INVISIBLE);
mNotificationButton.setAlpha(1f);
}
}
public void flipToNotifications(boolean animate) {
mSettingsButton.setVisibility(View.VISIBLE);
if (animate) {
mNotificationButtonAnim = start(
setVisibilityWhenDone(
ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
.setDuration(FLIP_DURATION_OUT),
mNotificationButton, View.INVISIBLE));
mSettingsButtonAnim = start(
startDelay(FLIP_DURATION_OUT,
ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
.setDuration(FLIP_DURATION_IN)));
} else {
mNotificationButton.setVisibility(View.INVISIBLE);
mNotificationButton.setAlpha(0f);
mSettingsButton.setAlpha(1f);
}
}
public void cancel() {
cancelAnim(mSettingsButtonAnim);
cancelAnim(mNotificationButtonAnim);
}
public void setVisibility(int vis) {
mHolder.setVisibility(vis);
}
return mNotificationPanel;
}
}

View File

@@ -220,8 +220,6 @@ public class PhoneStatusBarView extends PanelBar {
panel.setAlpha(alpha);
}
mBar.animateHeadsUp(mNotificationPanel == panel, mPanelExpandedFractionSum);
mBar.updateCarrierLabelVisibility(false);
mBar.userActivity();
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2014 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
*/
package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.android.systemui.R;
/**
* The view to manage the header area in the expanded status bar.
*/
public class StatusBarHeaderView extends RelativeLayout {
private boolean mExpanded;
private View mBackground;
private View mFlipper;
private int mCollapsedHeight;
private int mExpandedHeight;
public StatusBarHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mBackground = findViewById(R.id.background);
mFlipper = findViewById(R.id.header_flipper);
loadDimens();
}
private void loadDimens() {
mCollapsedHeight = getResources().getDimensionPixelSize(
R.dimen.status_bar_header_height);
mExpandedHeight = getResources().getDimensionPixelSize(
R.dimen.status_bar_header_height_expanded);
}
public int getCollapsedHeight() {
return mCollapsedHeight;
}
public int getExpandedHeight() {
return mExpandedHeight;
}
public void setExpanded(boolean expanded) {
if (expanded != mExpanded) {
ViewGroup.LayoutParams lp = getLayoutParams();
lp.height = expanded ? mExpandedHeight : mCollapsedHeight;
setLayoutParams(lp);
mExpanded = expanded;
}
}
public void setExpansionEnabled(boolean enabled) {
mFlipper.setVisibility(enabled ? View.VISIBLE : View.GONE);
}
public void setExpansion(float height) {
if (height < mCollapsedHeight) {
height = mCollapsedHeight;
}
if (height > mExpandedHeight) {
height = mExpandedHeight;
}
if (mExpanded) {
mBackground.setTranslationY(-(mExpandedHeight - height));
} else {
mBackground.setTranslationY(0);
}
}
public View getBackgroundView() {
return mBackground;
}
}

View File

@@ -56,11 +56,14 @@ public class StatusBarWindowView extends FrameLayout {
@Override
protected boolean fitSystemWindows(Rect insets) {
if (getFitsSystemWindows()) {
setPadding(insets.left, insets.top, insets.right, insets.bottom);
setPadding(insets.left, insets.top, insets.right, 0);
insets.left = 0;
insets.top = 0;
insets.right = 0;
} else {
setPadding(0, 0, 0, 0);
}
return true;
return false;
}
@Override

View File

@@ -492,6 +492,9 @@ public class NotificationStackScrollLayout extends ViewGroup
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!isEnabled()) {
return false;
}
boolean scrollerWantsIt = false;
if (!mSwipingInProgress) {
scrollerWantsIt = onScrollTouch(ev);

View File

@@ -120,11 +120,6 @@ public class TvStatusBar extends BaseStatusBar {
protected void updateExpandedViewPos(int expandedPosition) {
}
@Override
protected int getExpandedViewMaxHeight() {
return 0;
}
@Override
protected boolean shouldDisableNavbarGestures() {
return true;