Source code
package android.support.design.internal;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.design.R;
import android.support.v4.view.GravityCompat;
import android.support.v7.widget.LinearLayoutCompat;
import android.util.AttributeSet;
import android.view.Gravity;
public class ForegroundLinearLayout extends LinearLayoutCompat {
private Drawable mForeground;
boolean mForegroundBoundsChanged;
private int mForegroundGravity;
protected boolean mForegroundInPadding;
private final Rect mOverlayBounds;
private final Rect mSelfBounds;
public ForegroundLinearLayout(Context context) {
super(context);
this.mSelfBounds = new Rect();
this.mOverlayBounds = new Rect();
this.mForegroundGravity = 119;
this.mForegroundInPadding = true;
this.mForegroundBoundsChanged = false;
}
public ForegroundLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ForegroundLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mSelfBounds = new Rect();
this.mOverlayBounds = new Rect();
this.mForegroundGravity = 119;
this.mForegroundInPadding = true;
this.mForegroundBoundsChanged = false;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundLinearLayout, defStyle, 0);
this.mForegroundGravity = a.getInt(R.styleable.ForegroundLinearLayout_android_foregroundGravity, this.mForegroundGravity);
Drawable d = a.getDrawable(R.styleable.ForegroundLinearLayout_android_foreground);
if (d != null) {
setForeground(d);
}
this.mForegroundInPadding = a.getBoolean(R.styleable.ForegroundLinearLayout_foregroundInsidePadding, true);
a.recycle();
}
public int getForegroundGravity() {
return this.mForegroundGravity;
}
public void setForegroundGravity(int foregroundGravity) {
if (this.mForegroundGravity != foregroundGravity) {
if ((GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK & foregroundGravity) == 0) {
foregroundGravity |= 8388611;
}
if ((foregroundGravity & 112) == 0) {
foregroundGravity |= 48;
}
this.mForegroundGravity = foregroundGravity;
if (this.mForegroundGravity == 119 && this.mForeground != null) {
this.mForeground.getPadding(new Rect());
}
requestLayout();
}
}
protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who) || who == this.mForeground;
}
public void jumpDrawablesToCurrentState() {
super.jumpDrawablesToCurrentState();
if (this.mForeground != null) {
this.mForeground.jumpToCurrentState();
}
}
protected void drawableStateChanged() {
super.drawableStateChanged();
if (this.mForeground != null && this.mForeground.isStateful()) {
this.mForeground.setState(getDrawableState());
}
}
public void setForeground(Drawable drawable) {
if (this.mForeground != drawable) {
if (this.mForeground != null) {
this.mForeground.setCallback(null);
unscheduleDrawable(this.mForeground);
}
this.mForeground = drawable;
if (drawable != null) {
setWillNotDraw(false);
drawable.setCallback(this);
if (drawable.isStateful()) {
drawable.setState(getDrawableState());
}
if (this.mForegroundGravity == 119) {
drawable.getPadding(new Rect());
}
} else {
setWillNotDraw(true);
}
requestLayout();
invalidate();
}
}
public Drawable getForeground() {
return this.mForeground;
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
this.mForegroundBoundsChanged |= changed;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.mForegroundBoundsChanged = true;
}
public void draw(@NonNull Canvas canvas) {
super.draw(canvas);
if (this.mForeground != null) {
Drawable foreground = this.mForeground;
if (this.mForegroundBoundsChanged) {
this.mForegroundBoundsChanged = false;
Rect selfBounds = this.mSelfBounds;
Rect overlayBounds = this.mOverlayBounds;
int w = getRight() - getLeft();
int h = getBottom() - getTop();
if (this.mForegroundInPadding) {
selfBounds.set(0, 0, w, h);
} else {
selfBounds.set(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom());
}
Gravity.apply(this.mForegroundGravity, foreground.getIntrinsicWidth(), foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
foreground.setBounds(overlayBounds);
}
foreground.draw(canvas);
}
}
public void drawableHotspotChanged(float x, float y) {
super.drawableHotspotChanged(x, y);
if (this.mForeground != null) {
this.mForeground.setHotspot(x, y);
}
}
}