diff options
author | Daniel Sandler <dsandler@google.com> | 2011-06-13 07:29:39 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-13 07:29:39 -0700 |
commit | e0b4fe59f7e16451f4b957b7cb10ab650fbbe574 (patch) | |
tree | 31c4ee564feab7defdedb6e661fd9995b16a522d | |
parent | 5891f55a1614e0101645a8a5295f25e13aeb37a4 (diff) | |
parent | d42497e516521891a9d6ffa0daab75ef016725f5 (diff) | |
download | frameworks_base-e0b4fe59f7e16451f4b957b7cb10ab650fbbe574.zip frameworks_base-e0b4fe59f7e16451f4b957b7cb10ab650fbbe574.tar.gz frameworks_base-e0b4fe59f7e16451f4b957b7cb10ab650fbbe574.tar.bz2 |
Merge "Rebuilt notification list using a new custom layout."
8 files changed, 289 insertions, 11 deletions
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml index 8e456b2..93085d7 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml @@ -1,6 +1,6 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="65dp" + android:layout_height="@dimen/notification_height" > <ImageButton diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 18e8273..6670eff 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -18,7 +18,9 @@ */ --> -<com.android.systemui.statusbar.phone.ExpandedView xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.systemui.statusbar.phone.ExpandedView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" @@ -97,10 +99,11 @@ android:textAppearance="@style/TextAppearance.StatusBar.Title" android:text="@string/status_bar_ongoing_events_title" /> - <LinearLayout android:id="@+id/ongoingItems" + <com.android.systemui.statusbar.policy.NotificationRowLayout + android:id="@+id/ongoingItems" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" + systemui:rowHeight="@dimen/notification_height" /> <TextView android:id="@+id/latestTitle" @@ -111,10 +114,11 @@ android:textAppearance="@style/TextAppearance.StatusBar.Title" android:text="@string/status_bar_latest_events_title" /> - <LinearLayout android:id="@+id/latestItems" + <com.android.systemui.statusbar.policy.NotificationRowLayout + android:id="@+id/latestItems" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" + systemui:rowHeight="@dimen/notification_height" /> </LinearLayout> </ScrollView> diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml index 8e456b2..93085d7 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_row.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml @@ -1,6 +1,6 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="65dp" + android:layout_height="@dimen/notification_height" > <ImageButton diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index fb2f7d63..5291629 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -24,5 +24,8 @@ <declare-styleable name="NotificationLinearLayout"> <attr name="insetLeft" format="dimension" /> </declare-styleable> + <declare-styleable name="NotificationRowLayout"> + <attr name="rowHeight" format="dimension" /> + </declare-styleable> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 657dc46..5f0fbef 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -47,5 +47,8 @@ <!-- thickness (height) of the navigation bar on phones that require it --> <dimen name="navigation_bar_size">42dp</dimen> + + <!-- thickness (height) of each notification row, including any separators or padding --> + <dimen name="notification_height">65dp</dimen> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java index 92b8976..51fc7c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import android.animation.LayoutTransition; import android.content.Context; import android.util.AttributeSet; import android.view.Display; @@ -37,6 +38,8 @@ public class ExpandedView extends LinearLayout { @Override protected void onFinishInflate() { super.onFinishInflate(); + + setLayerType(LAYER_TYPE_HARDWARE, null); } /** We want to shrink down to 0, and ignore the background. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 00de920..3d15a1d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -130,11 +130,11 @@ public class PhoneStatusBar extends StatusBar { // ongoing NotificationData mOngoing = new NotificationData(); TextView mOngoingTitle; - LinearLayout mOngoingItems; + ViewGroup mOngoingItems; // latest NotificationData mLatest = new NotificationData(); TextView mLatestTitle; - LinearLayout mLatestItems; + ViewGroup mLatestItems; // position int[] mPositionTmp = new int[2]; boolean mExpanded; @@ -268,9 +268,9 @@ public class PhoneStatusBar extends StatusBar { mExpandedView = expanded; mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout); mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle); - mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems); + mOngoingItems = (ViewGroup)expanded.findViewById(R.id.ongoingItems); mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle); - mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems); + mLatestItems = (ViewGroup)expanded.findViewById(R.id.latestItems); mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle); mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button); mClearButton.setOnClickListener(mClearButtonListener); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java new file mode 100644 index 0000000..24eee27 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java @@ -0,0 +1,265 @@ +/* + * 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. + */ + +package com.android.systemui.statusbar.policy; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.Slog; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.HashSet; + +import com.android.systemui.R; + +public class NotificationRowLayout extends ViewGroup { + private static final String TAG = "NotificationRowLayout"; + private static final boolean DEBUG = false; + + private static final boolean ANIMATE_LAYOUT = true; + + private static final int ANIM_LEN = DEBUG ? 5000 : 250; + + Rect mTmpRect = new Rect(); + int mNumRows = 0; + int mRowHeight = 0; + int mHeight = 0; + + HashSet<View> mAppearingViews = new HashSet<View>(); + HashSet<View> mDisappearingViews = new HashSet<View>(); + + public NotificationRowLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public NotificationRowLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationRowLayout, + defStyle, 0); + mRowHeight = a.getDimensionPixelSize(R.styleable.NotificationRowLayout_rowHeight, 0); + a.recycle(); + + setLayoutTransition(null); + + if (DEBUG) { + setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { + @Override + public void onChildViewAdded(View parent, View child) { + Slog.d(TAG, "view added: " + child + "; new count: " + getChildCount()); + } + @Override + public void onChildViewRemoved(View parent, View child) { + Slog.d(TAG, "view removed: " + child + "; new count: " + (getChildCount() - 1)); + } + }); + + setBackgroundColor(0x80FF8000); + } + + } + + //** + @Override + public void addView(View child, int index, LayoutParams params) { + super.addView(child, index, params); + + final View childF = child; + + if (ANIMATE_LAYOUT) { + mAppearingViews.add(child); + + child.setPivotY(0); + AnimatorSet a = new AnimatorSet(); + a.playTogether( + ObjectAnimator.ofFloat(child, "alpha", 0f, 1f) +// ,ObjectAnimator.ofFloat(child, "scaleY", 0f, 1f) + ); + a.setDuration(ANIM_LEN); + a.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAppearingViews.remove(childF); + } + }); + a.start(); + requestLayout(); // start the container animation + } + } + + @Override + public void removeView(View child) { + final View childF = child; + if (ANIMATE_LAYOUT) { + if (mAppearingViews.contains(child)) { + mAppearingViews.remove(child); + } + mDisappearingViews.add(child); + + child.setPivotY(0); + AnimatorSet a = new AnimatorSet(); + a.playTogether( + ObjectAnimator.ofFloat(child, "alpha", 0f) +// ,ObjectAnimator.ofFloat(child, "scaleY", 0f) + ,ObjectAnimator.ofFloat(child, "translationX", 300f) + ); + a.setDuration(ANIM_LEN); + a.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + NotificationRowLayout.super.removeView(childF); + childF.setAlpha(1f); + mDisappearingViews.remove(childF); + } + }); + a.start(); + requestLayout(); // start the container animation + } else { + super.removeView(child); + } + } + //** + + @Override + public void onFinishInflate() { + super.onFinishInflate(); + setWillNotDraw(false); + } + + @Override + public void onDraw(android.graphics.Canvas c) { + super.onDraw(c); + if (DEBUG) { + Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: " + + getMeasuredHeight() + "px"); + c.save(); + c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6, + android.graphics.Region.Op.DIFFERENCE); + c.drawColor(0xFFFF8000); + c.restore(); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int count = getChildCount(); + + // pass 1: count the number of non-GONE views + int numRows = 0; + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; + } + if (mDisappearingViews.contains(child)) { + continue; + } + numRows++; + } + if (numRows != mNumRows) { + // uh oh, now you made us go and do work + + final int computedHeight = numRows * mRowHeight; + if (DEBUG) { + Slog.d(TAG, String.format("rows went from %d to %d, resizing to %dpx", + mNumRows, numRows, computedHeight)); + } + + mNumRows = numRows; + + if (ANIMATE_LAYOUT && isShown()) { + ObjectAnimator.ofInt(this, "forcedHeight", computedHeight) + .setDuration(ANIM_LEN) + .start(); + } else { + setForcedHeight(computedHeight); + } + } + + // pass 2: you know, do the measuring + final int childWidthMS = widthMeasureSpec; + final int childHeightMS = MeasureSpec.makeMeasureSpec( + mRowHeight, MeasureSpec.EXACTLY); + + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; + } + + child.measure(childWidthMS, childHeightMS); + } + + setMeasuredDimension( + getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), + resolveSize(getForcedHeight(), heightMeasureSpec)); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + final int width = right - left; + final int height = bottom - top; + + if (DEBUG) Slog.d(TAG, "onLayout: height=" + height); + + final int count = getChildCount(); + int y = 0; + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; + } +// final int thisRowHeight = (int)( +// ((mAppearingViews.contains(child) || mDisappearingViews.contains(child)) +// ? child.getScaleY() +// : 1.0f) +// * mRowHeight); + final int thisRowHeight = (int)(child.getAlpha() * mRowHeight); +// child.layout(0, y, width, y + thisRowHeight); + child.layout(0, y, width, y + mRowHeight); + y += thisRowHeight; + } + } + + public void setForcedHeight(int h) { + if (DEBUG) Slog.d(TAG, "forcedHeight: " + h); + if (h != mHeight) { + mHeight = h; + requestLayout(); + } + } + + public int getForcedHeight() { + return mHeight; + } +} |