Stop trying to draw a view not attached to the view tree

The behavior of the framework when we try to do so is undefined. In our
case, it almost work, but no clipping is applied, which is a problem for
Android S (before that, widget couldn't use clipping in the first
place).

Instead of drawing the view through a drawable, this really add the view
and adds also a badge ImageView for badges instead of drawing them
indirectly.

Note that, temporarily, we have to re-allow drawing the view after it
has been attached, but the underlying framework bug being fixed, this
should be fine (I tested it and it really seems to be).

Bug: 183609936
Test: Using hand designed app (see bug)
Change-Id: I929ef8fc81c98c49406f2d940cd5efc28319886d
This commit is contained in:
Pierre Barbier de Reuille
2021-03-25 16:44:40 +00:00
parent ce271c1067
commit ad41a56166
8 changed files with 137 additions and 85 deletions
@@ -25,7 +25,6 @@ import android.util.AttributeSet;
import android.view.View;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
/**
* View that draws a bitmap horizontally centered. If the image width is greater than the view
@@ -37,7 +36,6 @@ public class WidgetImageView extends View {
private final int mBadgeMargin;
private Drawable mDrawable;
private Drawable mBadge;
public WidgetImageView(Context context) {
this(context, null);
@@ -54,9 +52,9 @@ public class WidgetImageView extends View {
.getDimensionPixelSize(R.dimen.profile_badge_margin);
}
public void setDrawable(Drawable drawable, Drawable badge) {
/** Set the drawable to use for this view. */
public void setDrawable(Drawable drawable) {
mDrawable = drawable;
mBadge = badge;
invalidate();
}
@@ -70,11 +68,6 @@ public class WidgetImageView extends View {
updateDstRectF();
mDrawable.setBounds(getBitmapBounds());
mDrawable.draw(canvas);
// Only draw the badge if a preview was drawn.
if (mBadge != null) {
mBadge.draw(canvas);
}
}
}
@@ -105,17 +98,6 @@ public class WidgetImageView extends View {
mDstRectF.top = (myHeight - scaledHeight) / 2;
mDstRectF.bottom = (myHeight + scaledHeight) / 2;
}
if (mBadge != null) {
Rect bounds = mBadge.getBounds();
int left = Utilities.boundToRange(
(int) (mDstRectF.right + mBadgeMargin - bounds.width()),
mBadgeMargin, getWidth() - bounds.width());
int top = Utilities.boundToRange(
(int) (mDstRectF.bottom + mBadgeMargin - bounds.height()),
mBadgeMargin, getHeight() - bounds.height());
mBadge.setBounds(left, top, bounds.width() + left, bounds.height() + top);
}
}
/**