Merge "Animate in share/edit buttons immediately."
This commit is contained in:
committed by
Android (Google) Code Review
commit
4cb5c00b8e
@@ -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"/>
|
||||
@@ -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"
|
||||
|
||||
@@ -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"/>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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] -->
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user