* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
*/
protected boolean mShouldTranslateContents;
- private boolean mClipRoundedToClipTopAmount;
+ private boolean mTopAmountRounded;
private float mDistanceToTopRoundness = -1;
private float mExtraWidthForClipping;
private int mMinimumHeightForClipping = 0;
@Override
public void getOutline(View view, Outline outline) {
if (!mCustomOutline && mCurrentTopRoundness == 0.0f
- && mCurrentBottomRoundness == 0.0f && !mAlwaysRoundBothCorners) {
+ && mCurrentBottomRoundness == 0.0f && !mAlwaysRoundBothCorners
+ && !mTopAmountRounded) {
int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
int left = Math.max(translation, 0);
int top = mClipTopAmount + mBackgroundTop;
return EMPTY_PATH;
}
float topRoundness = mAlwaysRoundBothCorners
- ? mOutlineRadius : mCurrentTopRoundness * mOutlineRadius;
+ ? mOutlineRadius : getCurrentBackgroundRadiusTop();
float bottomRoundness = mAlwaysRoundBothCorners
- ? mOutlineRadius : mCurrentBottomRoundness * mOutlineRadius;
+ ? mOutlineRadius : getCurrentBackgroundRadiusBottom();
if (topRoundness + bottomRoundness > height) {
float overShoot = topRoundness + bottomRoundness - height;
topRoundness -= overShoot * mCurrentTopRoundness
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
canvas.save();
Path intersectPath = null;
- if (mClipRoundedToClipTopAmount) {
+ if (mTopAmountRounded && topAmountNeedsClipping()) {
int left = (int) (- mExtraWidthForClipping / 2.0f);
int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
int right = getWidth() + (int) (mExtraWidthForClipping + left);
public void setDistanceToTopRoundness(float distanceToTopRoundness) {
super.setDistanceToTopRoundness(distanceToTopRoundness);
if (distanceToTopRoundness != mDistanceToTopRoundness) {
- mClipRoundedToClipTopAmount = distanceToTopRoundness >= 0;
+ mTopAmountRounded = distanceToTopRoundness >= 0;
mDistanceToTopRoundness = distanceToTopRoundness;
- invalidate();
+ applyRoundness();
}
}
return false;
}
+ public boolean topAmountNeedsClipping() {
+ return true;
+ }
+
protected boolean isClippingNeeded() {
return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
-
}
private void initDimens() {
}
public float getCurrentBackgroundRadiusTop() {
+ // If this view is top amount notification view, it should always has round corners on top.
+ // It will be applied with applyRoundness()
+ if (mTopAmountRounded) {
+ return mOutlineRadius;
+ }
return mCurrentTopRoundness * mOutlineRadius;
}
private int mDrawableAlpha = 255;
private boolean mIsPressedAllowed;
+ private boolean mTopAmountRounded;
+ private float mDistanceToTopRoundness;
+
public NotificationBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
mDontModifyCorners = getResources().getBoolean(
private void draw(Canvas canvas, Drawable drawable) {
if (drawable != null) {
+ int top = mBackgroundTop;
int bottom = mActualHeight;
if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning) {
bottom -= mClipBottomAmount;
left = (int) ((getWidth() - mActualWidth) / 2.0f);
right = (int) (left + mActualWidth);
}
- drawable.setBounds(left, mBackgroundTop, right, bottom);
+ if (mTopAmountRounded) {
+ int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness);
+ top += clipTop;
+ if (clipTop >= 0) {
+ bottom += clipTop;
+ }
+ }
+ drawable.setBounds(left, top, right, bottom);
drawable.draw(canvas);
}
}
invalidate();
}
+ public void setDistanceToTopRoundness(float distanceToTopRoundness) {
+ if (distanceToTopRoundness != mDistanceToTopRoundness) {
+ mTopAmountRounded = distanceToTopRoundness >= 0;
+ mDistanceToTopRoundness = distanceToTopRoundness;
+ invalidate();
+ }
+ }
+
@Override
public boolean hasOverlappingRendering() {
}
public void setRoundness(float topRoundness, float bottomRoundNess) {
+ if (topRoundness == mCornerRadii[0] && bottomRoundNess == mCornerRadii[4]) {
+ return;
+ }
mBottomIsRounded = bottomRoundNess != 0.0f;
mCornerRadii[0] = topRoundness;
mCornerRadii[1] = topRoundness;