fixes more error
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.wm.shell.draganddrop;
|
||||
|
||||
import static com.android.wm.shell.animation.Interpolators.FAST_OUT_SLOW_IN;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.policy.ScreenDecorationsUtils;
|
||||
import com.android.wm.shell.R;
|
||||
|
||||
/**
|
||||
* Renders a drop zone area for items being dragged.
|
||||
*/
|
||||
public class DropZoneView extends FrameLayout {
|
||||
|
||||
private static final float SPLASHSCREEN_ALPHA = 0.90f;
|
||||
private static final float HIGHLIGHT_ALPHA = 1f;
|
||||
private static final int MARGIN_ANIMATION_ENTER_DURATION = 400;
|
||||
private static final int MARGIN_ANIMATION_EXIT_DURATION = 250;
|
||||
|
||||
private static final FloatProperty<DropZoneView> INSETS =
|
||||
new FloatProperty<DropZoneView>("insets") {
|
||||
@Override
|
||||
public void setValue(DropZoneView v, float percent) {
|
||||
v.setMarginPercent(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(DropZoneView v) {
|
||||
return v.getMarginPercent();
|
||||
}
|
||||
};
|
||||
|
||||
private final Path mPath = new Path();
|
||||
private final float[] mContainerMargin = new float[4];
|
||||
private float mCornerRadius;
|
||||
private float mBottomInset;
|
||||
private boolean mIgnoreBottomMargin;
|
||||
private int mMarginColor; // i.e. color used for negative space like the container insets
|
||||
|
||||
private boolean mShowingHighlight;
|
||||
private boolean mShowingSplash;
|
||||
private boolean mShowingMargin;
|
||||
|
||||
private int mSplashScreenColor;
|
||||
private int mHighlightColor;
|
||||
|
||||
private ObjectAnimator mBackgroundAnimator;
|
||||
private ObjectAnimator mMarginAnimator;
|
||||
private float mMarginPercent;
|
||||
|
||||
// Renders a highlight or neutral transparent color
|
||||
private ColorDrawable mColorDrawable;
|
||||
// Renders the translucent splashscreen with the app icon in the middle
|
||||
private ImageView mSplashScreenView;
|
||||
// Renders the margin / insets around the dropzone container
|
||||
private MarginView mMarginView;
|
||||
|
||||
public DropZoneView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public DropZoneView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public DropZoneView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public DropZoneView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
setContainerMargin(0, 0, 0, 0); // make sure it's populated
|
||||
|
||||
mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
|
||||
mMarginColor = getResources().getColor(R.color.taskbar_background_dark);
|
||||
int c = getResources().getColor(android.R.color.system_accent1_500);
|
||||
mHighlightColor = Color.argb(HIGHLIGHT_ALPHA, Color.red(c), Color.green(c), Color.blue(c));
|
||||
mSplashScreenColor = Color.argb(SPLASHSCREEN_ALPHA, 0, 0, 0);
|
||||
mColorDrawable = new ColorDrawable();
|
||||
setBackgroundDrawable(mColorDrawable);
|
||||
|
||||
final int iconSize = context.getResources().getDimensionPixelSize(R.dimen.split_icon_size);
|
||||
mSplashScreenView = new ImageView(context);
|
||||
mSplashScreenView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
addView(mSplashScreenView,
|
||||
new FrameLayout.LayoutParams(iconSize, iconSize, Gravity.CENTER));
|
||||
mSplashScreenView.setAlpha(0f);
|
||||
|
||||
mMarginView = new MarginView(context);
|
||||
addView(mMarginView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
}
|
||||
|
||||
public void onThemeChange() {
|
||||
mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(getContext());
|
||||
mMarginColor = getResources().getColor(R.color.taskbar_background_dark);
|
||||
mHighlightColor = getResources().getColor(android.R.color.system_accent1_500);
|
||||
|
||||
if (mMarginPercent > 0) {
|
||||
mMarginView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the desired margins around the drop zone container when fully showing. */
|
||||
public void setContainerMargin(float left, float top, float right, float bottom) {
|
||||
mContainerMargin[0] = left;
|
||||
mContainerMargin[1] = top;
|
||||
mContainerMargin[2] = right;
|
||||
mContainerMargin[3] = bottom;
|
||||
if (mMarginPercent > 0) {
|
||||
mMarginView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/** Ignores the bottom margin provided by the insets. */
|
||||
public void setForceIgnoreBottomMargin(boolean ignoreBottomMargin) {
|
||||
mIgnoreBottomMargin = ignoreBottomMargin;
|
||||
if (mMarginPercent > 0) {
|
||||
mMarginView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the bottom inset so the drop zones are above bottom navigation. */
|
||||
public void setBottomInset(float bottom) {
|
||||
mBottomInset = bottom;
|
||||
((LayoutParams) mSplashScreenView.getLayoutParams()).bottomMargin = (int) bottom;
|
||||
if (mMarginPercent > 0) {
|
||||
mMarginView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the color and icon to use for the splashscreen when shown. */
|
||||
public void setAppInfo(int color, Drawable appIcon) {
|
||||
Color c = Color.valueOf(color);
|
||||
mSplashScreenColor = Color.argb(SPLASHSCREEN_ALPHA, c.red(), c.green(), c.blue());
|
||||
mSplashScreenView.setImageDrawable(appIcon);
|
||||
}
|
||||
|
||||
/** @return an active animator for this view if one exists. */
|
||||
@Nullable
|
||||
public Animator getAnimator() {
|
||||
if (mMarginAnimator != null && mMarginAnimator.isRunning()) {
|
||||
return mMarginAnimator;
|
||||
} else if (mBackgroundAnimator != null && mBackgroundAnimator.isRunning()) {
|
||||
return mBackgroundAnimator;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Animates between highlight and splashscreen depending on current state. */
|
||||
public void animateSwitch() {
|
||||
mShowingHighlight = !mShowingHighlight;
|
||||
mShowingSplash = !mShowingHighlight;
|
||||
final int newColor = mShowingHighlight ? mHighlightColor : mSplashScreenColor;
|
||||
animateBackground(mColorDrawable.getColor(), newColor);
|
||||
animateSplashScreenIcon();
|
||||
}
|
||||
|
||||
/** Animates the highlight indicating the zone is hovered on or not. */
|
||||
public void setShowingHighlight(boolean showingHighlight) {
|
||||
mShowingHighlight = showingHighlight;
|
||||
mShowingSplash = !mShowingHighlight;
|
||||
final int newColor = mShowingHighlight ? mHighlightColor : mSplashScreenColor;
|
||||
animateBackground(Color.TRANSPARENT, newColor);
|
||||
animateSplashScreenIcon();
|
||||
}
|
||||
|
||||
/** Animates the margins around the drop zone to show or hide. */
|
||||
public void setShowingMargin(boolean visible) {
|
||||
if (mShowingMargin != visible) {
|
||||
mShowingMargin = visible;
|
||||
animateMarginToState();
|
||||
}
|
||||
if (!mShowingMargin) {
|
||||
mShowingHighlight = false;
|
||||
mShowingSplash = false;
|
||||
animateBackground(mColorDrawable.getColor(), Color.TRANSPARENT);
|
||||
animateSplashScreenIcon();
|
||||
}
|
||||
}
|
||||
|
||||
private void animateBackground(int startColor, int endColor) {
|
||||
if (mBackgroundAnimator != null) {
|
||||
mBackgroundAnimator.cancel();
|
||||
}
|
||||
mBackgroundAnimator = ObjectAnimator.ofArgb(mColorDrawable,
|
||||
"color",
|
||||
startColor,
|
||||
endColor);
|
||||
if (!mShowingSplash && !mShowingHighlight) {
|
||||
mBackgroundAnimator.setInterpolator(FAST_OUT_SLOW_IN);
|
||||
}
|
||||
mBackgroundAnimator.start();
|
||||
}
|
||||
|
||||
private void animateSplashScreenIcon() {
|
||||
mSplashScreenView.animate().alpha(mShowingSplash ? 1f : 0f).start();
|
||||
}
|
||||
|
||||
private void animateMarginToState() {
|
||||
if (mMarginAnimator != null) {
|
||||
mMarginAnimator.cancel();
|
||||
}
|
||||
mMarginAnimator = ObjectAnimator.ofFloat(this, INSETS,
|
||||
mMarginPercent,
|
||||
mShowingMargin ? 1f : 0f);
|
||||
mMarginAnimator.setInterpolator(FAST_OUT_SLOW_IN);
|
||||
mMarginAnimator.setDuration(mShowingMargin
|
||||
? MARGIN_ANIMATION_ENTER_DURATION
|
||||
: MARGIN_ANIMATION_EXIT_DURATION);
|
||||
mMarginAnimator.start();
|
||||
}
|
||||
|
||||
private void setMarginPercent(float percent) {
|
||||
if (percent != mMarginPercent) {
|
||||
mMarginPercent = percent;
|
||||
mMarginView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private float getMarginPercent() {
|
||||
return mMarginPercent;
|
||||
}
|
||||
|
||||
/** Simple view that draws a rounded rect margin around its contents. **/
|
||||
private class MarginView extends View {
|
||||
|
||||
MarginView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
mPath.reset();
|
||||
mPath.addRoundRect(mContainerMargin[0] * mMarginPercent,
|
||||
mContainerMargin[1] * mMarginPercent,
|
||||
getWidth() - (mContainerMargin[2] * mMarginPercent),
|
||||
getHeight() - (mContainerMargin[3] * mMarginPercent)
|
||||
- (mIgnoreBottomMargin ? 0 : mBottomInset),
|
||||
mCornerRadius * mMarginPercent,
|
||||
mCornerRadius * mMarginPercent,
|
||||
Path.Direction.CW);
|
||||
mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);
|
||||
canvas.clipPath(mPath);
|
||||
canvas.drawColor(mMarginColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user