summaryrefslogtreecommitdiffstats
path: root/quickstep/src/com/android
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2018-03-26 15:33:41 -0700
committerSunny Goyal <sunnygoyal@google.com>2018-03-26 17:24:12 -0700
commit00c9c9a6fc551fef89658a11abe544248247f3b6 (patch)
treee1f452f350129fe10fda2c589522f500ab12976d /quickstep/src/com/android
parent3d58de67a87b589eacbf8b4d4e3872b7bb7576e7 (diff)
downloadandroid_packages_apps_Trebuchet-00c9c9a6fc551fef89658a11abe544248247f3b6.tar.gz
android_packages_apps_Trebuchet-00c9c9a6fc551fef89658a11abe544248247f3b6.tar.bz2
android_packages_apps_Trebuchet-00c9c9a6fc551fef89658a11abe544248247f3b6.zip
Adding an empty message in RecentsView
Moving the content instead of translating the view. This ensures that the empty message fades in place while the other content come-in from the side. Change-Id: I081d2e21206de24ad530814cb6a8ca7c3e293724
Diffstat (limited to 'quickstep/src/com/android')
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java2
-rw-r--r--quickstep/src/com/android/quickstep/FallbackRecentsView.java21
-rw-r--r--quickstep/src/com/android/quickstep/views/LauncherRecentsView.java32
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java94
4 files changed, 139 insertions, 10 deletions
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index d8f206c5e..5f94bcaf1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -56,6 +56,7 @@ public class RecentsViewStateController implements StateHandler {
mRecentsView.setTranslationXFactor(translationFactor[0]);
mRecentsView.setTranslationYFactor(translationFactor[1]);
if (state.overviewUi) {
+ mRecentsView.updateEmptyMessage();
mRecentsView.resetTaskVisuals();
}
}
@@ -94,6 +95,7 @@ public class RecentsViewStateController implements StateHandler {
});
updateAnim.setDuration(config.duration);
builder.play(updateAnim);
+ mRecentsView.updateEmptyMessage();
}
}
}
diff --git a/quickstep/src/com/android/quickstep/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/FallbackRecentsView.java
index 032d753a6..251e95806 100644
--- a/quickstep/src/com/android/quickstep/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/FallbackRecentsView.java
@@ -16,8 +16,10 @@
package com.android.quickstep;
import android.content.Context;
+import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.view.View;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
@@ -32,6 +34,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> implements
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOverviewStateEnabled(true);
+ updateEmptyMessage();
}
@Override
@@ -40,6 +43,18 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> implements
}
@Override
+ public void onViewAdded(View child) {
+ super.onViewAdded(child);
+ updateEmptyMessage();
+ }
+
+ @Override
+ public void onViewRemoved(View child) {
+ super.onViewRemoved(child);
+ updateEmptyMessage();
+ }
+
+ @Override
public void setInsets(Rect insets) {
mInsets.set(insets);
DeviceProfile dp = mActivity.getDeviceProfile();
@@ -65,4 +80,10 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> implements
grid.widthPx - targetPadding.right - insets.right,
grid.heightPx - targetPadding.bottom - insets.bottom);
}
+
+ @Override
+ public void draw(Canvas canvas) {
+ maybeDrawEmptyMessage(canvas);
+ super.draw(canvas);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 861b5fa03..34c3e4f05 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -19,10 +19,12 @@ import static com.android.launcher3.LauncherState.NORMAL;
import android.annotation.TargetApi;
import android.content.Context;
+import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.FloatProperty;
+import android.view.View;
import android.widget.FrameLayout;
import com.android.launcher3.DeviceProfile;
@@ -103,19 +105,12 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements Insett
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
-
- int width = right - left;
- setTranslationX(mTranslationXFactor * (mIsRtl ? -width : width));
setTranslationYFactor(mTranslationYFactor);
}
public void setTranslationXFactor(float translationFactor) {
mTranslationXFactor = translationFactor;
- setTranslationX(translationFactor * (mIsRtl ? -getWidth() : getWidth()));
- }
-
- public float getTranslationXFactor() {
- return mTranslationXFactor;
+ invalidate();
}
public void setTranslationYFactor(float translationFactor) {
@@ -123,7 +118,24 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements Insett
setTranslationY(mTranslationYFactor * (mPagePadding.bottom - mPagePadding.top));
}
- public float getTranslationYFactor() {
- return mTranslationYFactor;
+ @Override
+ public void draw(Canvas canvas) {
+ maybeDrawEmptyMessage(canvas);
+ int count = canvas.save();
+ canvas.translate(mTranslationXFactor * (mIsRtl ? -getWidth() : getWidth()), 0);
+ super.draw(canvas);
+ canvas.restoreToCount(count);
+ }
+
+ @Override
+ public void onViewAdded(View child) {
+ super.onViewAdded(child);
+ updateEmptyMessage();
+ }
+
+ @Override
+ protected void onTaskStackUpdated() {
+ // Lazily update the empty message only when the task stack is reapplied
+ updateEmptyMessage();
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8901e6d8c..f75d6bcf7 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -29,8 +29,14 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.graphics.Canvas;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -46,6 +52,7 @@ import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.Themes;
import com.android.quickstep.PendingAnimation;
import com.android.quickstep.QuickScrubController;
import com.android.quickstep.RecentsModel;
@@ -130,6 +137,15 @@ public abstract class RecentsView<T extends BaseActivity>
// Keeps track of task views whose visual state should not be reset
private ArraySet<TaskView> mIgnoreResetTaskViews = new ArraySet<>();
+ // Variables for empty state
+ private final Drawable mEmptyIcon;
+ private final CharSequence mEmptyMessage;
+ private final TextPaint mEmptyMessagePaint;
+ private final Point mLastMeasureSize = new Point();
+ private final int mEmptyMessagePadding;
+ private boolean mShowEmptyMessage;
+ private Layout mEmptyTextLayout;
+
public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
@@ -143,6 +159,17 @@ public abstract class RecentsView<T extends BaseActivity>
mModel = RecentsModel.getInstance(context);
onSharedPreferenceChanged(Utilities.getPrefs(context), PREF_FLIP_RECENTS);
+
+ mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
+ mEmptyIcon.setCallback(this);
+ mEmptyMessage = context.getText(R.string.recents_empty_message);
+ mEmptyMessagePaint = new TextPaint();
+ mEmptyMessagePaint.setColor(Themes.getAttrColor(context, android.R.attr.textColorPrimary));
+ mEmptyMessagePaint.setTextSize(getResources()
+ .getDimension(R.dimen.recents_empty_message_text_size));
+ mEmptyMessagePadding = getResources()
+ .getDimensionPixelSize(R.dimen.recents_empty_message_text_padding);
+ setWillNotDraw(false);
}
@Override
@@ -247,6 +274,7 @@ public abstract class RecentsView<T extends BaseActivity>
TaskStack stack = loadPlan != null ? loadPlan.getTaskStack() : null;
if (stack == null) {
removeAllViews();
+ onTaskStackUpdated();
return;
}
@@ -283,8 +311,11 @@ public abstract class RecentsView<T extends BaseActivity>
if (oldChildCount != getChildCount()) {
mQuickScrubController.snapToNextTaskIfAvailable();
}
+ onTaskStackUpdated();
}
+ protected void onTaskStackUpdated() { }
+
public void resetTaskVisuals() {
for (int i = getChildCount() - 1; i >= 0; i--) {
TaskView taskView = (TaskView) getChildAt(i);
@@ -700,6 +731,11 @@ public abstract class RecentsView<T extends BaseActivity>
for (int i = getChildCount() - 1; i >= 0; i--) {
getChildAt(i).setAlpha(alpha);
}
+
+ int alphaInt = Math.round(alpha * 255);
+ mEmptyMessagePaint.setAlpha(alphaInt);
+ mEmptyIcon.setAlpha(alphaInt);
+
setVisibility(alpha > 0 ? VISIBLE : GONE);
}
@@ -708,4 +744,62 @@ public abstract class RecentsView<T extends BaseActivity>
super.onViewAdded(child);
child.setAlpha(mContentAlpha);
}
+
+ public void updateEmptyMessage() {
+ boolean isEmpty = getChildCount() == 0;
+ boolean hasSizeChanged = mLastMeasureSize.x != getWidth()
+ || mLastMeasureSize.y != getHeight();
+ if (isEmpty == mShowEmptyMessage && !hasSizeChanged) {
+ return;
+ }
+ setContentDescription(isEmpty ? mEmptyMessage : "");
+ mShowEmptyMessage = isEmpty;
+ updateEmptyStateUi(hasSizeChanged);
+ invalidate();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ updateEmptyStateUi(changed);
+ }
+
+ private void updateEmptyStateUi(boolean sizeChanged) {
+ boolean hasValidSize = getWidth() > 0 && getHeight() > 0;
+ if (sizeChanged && hasValidSize) {
+ mEmptyTextLayout = null;
+ }
+
+ if (mShowEmptyMessage && hasValidSize && mEmptyTextLayout == null) {
+ mLastMeasureSize.set(getWidth(), getHeight());
+ int availableWidth = mLastMeasureSize.x - mEmptyMessagePadding - mEmptyMessagePadding;
+ mEmptyTextLayout = StaticLayout.Builder.obtain(mEmptyMessage, 0, mEmptyMessage.length(),
+ mEmptyMessagePaint, availableWidth)
+ .setAlignment(Layout.Alignment.ALIGN_CENTER)
+ .build();
+ int totalHeight = mEmptyTextLayout.getHeight()
+ + mEmptyMessagePadding + mEmptyIcon.getIntrinsicHeight();
+
+ int top = (mLastMeasureSize.y - totalHeight) / 2;
+ int left = (mLastMeasureSize.x - mEmptyIcon.getIntrinsicWidth()) / 2;
+ mEmptyIcon.setBounds(left, top, left + mEmptyIcon.getIntrinsicWidth(),
+ top + mEmptyIcon.getIntrinsicHeight());
+ }
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who) || (mShowEmptyMessage && who == mEmptyIcon);
+ }
+
+ protected void maybeDrawEmptyMessage(Canvas canvas) {
+ if (mShowEmptyMessage && mEmptyTextLayout != null) {
+ mEmptyIcon.draw(canvas);
+ canvas.save();
+ canvas.translate(mEmptyMessagePadding,
+ mEmptyIcon.getBounds().bottom + mEmptyMessagePadding);
+ mEmptyTextLayout.draw(canvas);
+ canvas.restore();
+ }
+ }
}