Merge "Animate in share/edit buttons immediately."

This commit is contained in:
Miranda Kephart
2020-10-15 19:35:05 +00:00
committed by Android (Google) Code Review
8 changed files with 135 additions and 73 deletions

View File

@@ -28,6 +28,6 @@
android:visibility="gone"
android:background="@drawable/screenshot_rounded_corners"
android:adjustViewBounds="true"
android:contentDescription="@string/screenshot_preview_description"
android:contentDescription="@string/screenshot_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

View File

@@ -19,7 +19,7 @@
android:id="@+id/global_screenshot_action_chip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screenshot_action_chip_margin_right"
android:layout_marginStart="@dimen/screenshot_action_chip_margin_start"
android:paddingVertical="@dimen/screenshot_action_chip_margin_vertical"
android:layout_gravity="center"
android:gravity="center"

View File

@@ -28,6 +28,6 @@
android:visibility="gone"
android:background="@drawable/screenshot_rounded_corners"
android:adjustViewBounds="true"
android:contentDescription="@string/screenshot_preview_description"
android:contentDescription="@string/screenshot_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

View File

@@ -51,7 +51,12 @@
<LinearLayout
android:id="@+id/global_screenshot_actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content">
<include layout="@layout/global_screenshot_action_chip"
android:id="@+id/screenshot_share_chip"/>
<include layout="@layout/global_screenshot_action_chip"
android:id="@+id/screenshot_edit_chip"/>
</LinearLayout>
</HorizontalScrollView>
<include layout="@layout/global_screenshot_preview"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -323,7 +323,7 @@
<dimen name="screenshot_action_container_padding_right">8dp</dimen>
<!-- Radius of the chip background on global screenshot actions -->
<dimen name="screenshot_button_corner_radius">20dp</dimen>
<dimen name="screenshot_action_chip_margin_right">8dp</dimen>
<dimen name="screenshot_action_chip_margin_start">8dp</dimen>
<dimen name="screenshot_action_chip_margin_vertical">10dp</dimen>
<dimen name="screenshot_action_chip_padding_vertical">7dp</dimen>
<dimen name="screenshot_action_chip_icon_size">18dp</dimen>

View File

@@ -233,6 +233,8 @@
<!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
<string name="screenshot_failed_to_capture_text">Taking screenshots isn\'t allowed by the app or
your organization</string>
<!-- Content description indicating that tapping the element will allow editing the screenshot [CHAR LIMIT=NONE] -->
<string name="screenshot_edit">Edit screenshot</string>
<!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] -->
<string name="screenshot_dismiss_ui_description">Dismiss screenshot</string>
<!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] -->

View File

@@ -45,6 +45,7 @@ import android.graphics.Region;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.LayerDrawable;
import android.media.MediaActionSound;
@@ -194,6 +195,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private ImageView mActionsContainerBackground;
private HorizontalScrollView mActionsContainer;
private LinearLayout mActionsView;
private ScreenshotActionChip mShareChip;
private ScreenshotActionChip mEditChip;
private ImageView mBackgroundProtection;
private FrameLayout mDismissButton;
@@ -215,6 +218,14 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private int mLeftInset;
private int mRightInset;
private ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
private PendingInteraction mPendingInteraction;
private enum PendingInteraction {
PREVIEW,
EDIT,
SHARE
}
// standard material ease
private final Interpolator mFastOutSlowIn;
@@ -548,6 +559,9 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mOnCompleteRunnable.run();
});
mShareChip = mActionsContainer.findViewById(R.id.screenshot_share_chip);
mEditChip = mActionsContainer.findViewById(R.id.screenshot_edit_chip);
mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
mScreenshotLayout.setFocusable(true);
@@ -756,11 +770,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
createScreenshotActionsShadeAnimation(imageData).start();
setChipIntents(imageData);
}
});
} else {
createScreenshotActionsShadeAnimation(imageData).start();
setChipIntents(imageData);
}
});
}
@@ -895,19 +909,14 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mScreenshotAnimatedView.setVisibility(View.GONE);
mScreenshotPreview.setVisibility(View.VISIBLE);
mScreenshotLayout.forceLayout();
createScreenshotActionsShadeAnimation().start();
}
});
return dropInAnimation;
}
private ValueAnimator createScreenshotActionsShadeAnimation(SavedImageData imageData) {
LayoutInflater inflater = LayoutInflater.from(mContext);
mActionsView.removeAllViews();
mScreenshotLayout.invalidate();
mScreenshotLayout.requestLayout();
mScreenshotLayout.getViewTreeObserver().dispatchOnGlobalLayout();
private ValueAnimator createScreenshotActionsShadeAnimation() {
// By default the activities won't be able to start immediately; override this to keep
// the same behavior as if started from a notification
try {
@@ -917,61 +926,35 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
ArrayList<ScreenshotActionChip> chips = new ArrayList<>();
for (Notification.Action smartAction : imageData.smartActions) {
ScreenshotActionChip actionChip = (ScreenshotActionChip) inflater.inflate(
R.layout.global_screenshot_action_chip, mActionsView, false);
actionChip.setText(smartAction.title);
actionChip.setIcon(smartAction.getIcon(), false);
actionChip.setPendingIntent(smartAction.actionIntent,
() -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED);
dismissScreenshot("chip tapped", false);
mOnCompleteRunnable.run();
});
mActionsView.addView(actionChip);
chips.add(actionChip);
}
ScreenshotActionChip shareChip = (ScreenshotActionChip) inflater.inflate(
R.layout.global_screenshot_action_chip, mActionsView, false);
shareChip.setText(imageData.shareAction.title);
shareChip.setIcon(imageData.shareAction.getIcon(), true);
shareChip.setPendingIntent(imageData.shareAction.actionIntent, () -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED);
dismissScreenshot("chip tapped", false);
mOnCompleteRunnable.run();
mShareChip.setText(mContext.getString(com.android.internal.R.string.share));
mShareChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_share), true);
mShareChip.setOnClickListener(v -> {
mShareChip.setIsPending(true);
mEditChip.setIsPending(false);
mPendingInteraction = PendingInteraction.SHARE;
});
mActionsView.addView(shareChip);
chips.add(shareChip);
chips.add(mShareChip);
ScreenshotActionChip editChip = (ScreenshotActionChip) inflater.inflate(
R.layout.global_screenshot_action_chip, mActionsView, false);
editChip.setText(imageData.editAction.title);
editChip.setIcon(imageData.editAction.getIcon(), true);
editChip.setPendingIntent(imageData.editAction.actionIntent, () -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED);
dismissScreenshot("chip tapped", false);
mOnCompleteRunnable.run();
mEditChip.setText(mContext.getString(com.android.internal.R.string.screenshot_edit));
mEditChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_edit), true);
mEditChip.setOnClickListener(v -> {
mEditChip.setIsPending(true);
mShareChip.setIsPending(false);
mPendingInteraction = PendingInteraction.EDIT;
});
mActionsView.addView(editChip);
chips.add(editChip);
chips.add(mEditChip);
mScreenshotPreview.setOnClickListener(v -> {
try {
imageData.editAction.actionIntent.send();
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
dismissScreenshot("screenshot preview tapped", false);
mOnCompleteRunnable.run();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Intent cancelled", e);
}
mShareChip.setIsPending(false);
mEditChip.setIsPending(false);
mPendingInteraction = PendingInteraction.PREVIEW;
});
mScreenshotPreview.setContentDescription(imageData.editAction.title);
// remove the margin from the last chip so that it's correctly aligned with the end
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
mActionsView.getChildAt(mActionsView.getChildCount() - 1).getLayoutParams();
params.setMarginEnd(0);
mActionsView.getChildAt(0).getLayoutParams();
params.setMarginStart(0);
mActionsView.getChildAt(0).setLayoutParams(params);
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS);
@@ -1004,6 +987,63 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
return animator;
}
private void setChipIntents(SavedImageData imageData) {
mShareChip.setPendingIntent(imageData.shareAction.actionIntent, () -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED);
dismissScreenshot("chip tapped", false);
mOnCompleteRunnable.run();
});
mEditChip.setPendingIntent(imageData.editAction.actionIntent, () -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED);
dismissScreenshot("chip tapped", false);
mOnCompleteRunnable.run();
});
mScreenshotPreview.setOnClickListener(v -> {
try {
imageData.editAction.actionIntent.send();
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
dismissScreenshot("screenshot preview tapped", false);
mOnCompleteRunnable.run();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Intent cancelled", e);
}
});
if (mPendingInteraction != null) {
switch(mPendingInteraction) {
case PREVIEW:
mScreenshotPreview.callOnClick();
break;
case SHARE:
mShareChip.callOnClick();
break;
case EDIT:
mEditChip.callOnClick();
break;
}
} else {
LayoutInflater inflater = LayoutInflater.from(mContext);
for (Notification.Action smartAction : imageData.smartActions) {
ScreenshotActionChip actionChip = (ScreenshotActionChip) inflater.inflate(
R.layout.global_screenshot_action_chip, mActionsView, false);
actionChip.setText(smartAction.title);
actionChip.setIcon(smartAction.getIcon(), false);
actionChip.setPendingIntent(smartAction.actionIntent,
() -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED);
dismissScreenshot("chip tapped", false);
mOnCompleteRunnable.run();
});
actionChip.setAlpha(1);
mActionsView.addView(actionChip);
mSmartChips.add(actionChip);
}
}
}
private AnimatorSet createScreenshotDismissAnimation() {
ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
alphaAnim.setStartDelay(SCREENSHOT_DISMISS_ALPHA_OFFSET_MS);
@@ -1046,9 +1086,16 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mDismissButton.setVisibility(View.GONE);
mScreenshotPreview.setVisibility(View.GONE);
mScreenshotPreview.setLayerType(View.LAYER_TYPE_NONE, null);
mScreenshotPreview.setContentDescription(
mContext.getResources().getString(R.string.screenshot_preview_description));
mScreenshotPreview.setOnClickListener(null);
mShareChip.setOnClickListener(null);
mEditChip.setOnClickListener(null);
mShareChip.setIsPending(false);
mEditChip.setIsPending(false);
mPendingInteraction = null;
for (ScreenshotActionChip chip : mSmartChips) {
mActionsView.removeView(chip);
}
mSmartChips.clear();
mScreenshotLayout.setAlpha(1);
mDismissButton.setTranslationY(0);
mActionsContainer.setTranslationY(0);

View File

@@ -16,7 +16,6 @@
package com.android.systemui.screenshot;
import android.annotation.ColorInt;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.drawable.Icon;
@@ -35,9 +34,9 @@ public class ScreenshotActionChip extends FrameLayout {
private static final String TAG = "ScreenshotActionChip";
private ImageView mIcon;
private TextView mText;
private @ColorInt int mIconColor;
private ImageView mIconView;
private TextView mTextView;
private boolean mIsPending = false;
public ScreenshotActionChip(Context context) {
this(context, null);
@@ -54,25 +53,29 @@ public class ScreenshotActionChip extends FrameLayout {
public ScreenshotActionChip(
Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mIconColor = context.getColor(R.color.global_screenshot_button_icon);
}
@Override
protected void onFinishInflate() {
mIcon = findViewById(R.id.screenshot_action_chip_icon);
mText = findViewById(R.id.screenshot_action_chip_text);
mIconView = findViewById(R.id.screenshot_action_chip_icon);
mTextView = findViewById(R.id.screenshot_action_chip_text);
}
@Override
public void setPressed(boolean pressed) {
// override pressed state to true if there is an action pending
super.setPressed(mIsPending || pressed);
}
void setIcon(Icon icon, boolean tint) {
mIcon.setImageIcon(icon);
mIconView.setImageIcon(icon);
if (!tint) {
mIcon.setImageTintList(null);
mIconView.setImageTintList(null);
}
}
void setText(CharSequence text) {
mText.setText(text);
mTextView.setText(text);
}
void setPendingIntent(PendingIntent intent, Runnable finisher) {
@@ -85,4 +88,9 @@ public class ScreenshotActionChip extends FrameLayout {
}
});
}
void setIsPending(boolean isPending) {
mIsPending = isPending;
setPressed(mIsPending);
}
}