在xml中配置selector时,最终解析成java代码对应的是StateListDrawable(https://cs.android.com/android/platform/superproject/+/master:frameworks/base/graphics/java/android/graphics/drawable/DrawableInflater.java)。
当selector的xml被作为背景设置给控件时,setBackground时会处理drawable的padding会遍历item,选择出最大的let/right/bottom/top值作为padding,设置给当前的drawable.
//View.java android P
@Deprecated
public void setBackgroundDrawable(Drawable background) {
...
if (background != null) {
Rect padding = sThreadLocal.get();
if (padding == null) {
padding = new Rect();
sThreadLocal.set(padding);
}
resetResolvedDrawablesInternal();
background.setLayoutDirection(getLayoutDirection());
if (background.getPadding(padding)) {
...
}
...
} else {
...
}
...
}
DrawableContainer.java
@Override
public boolean getPadding(Rect padding) {
final Rect r = mDrawableContainerState.getConstantPadding();
boolean result;
if (r != null) {
padding.set(r);
result = (r.left | r.top | r.bottom | r.right) != 0;
} else {
if (mCurrDrawable != null) {
result = mCurrDrawable.getPadding(padding);
} else {
result = super.getPadding(padding);
}
}
if (needsMirroring()) {
final int left = padding.left;
final int right = padding.right;
padding.left = right;
padding.right = left;
}
return result;
}
public final Rect getConstantPadding() {
if (mVariablePadding) {
return null;
}
if ((mConstantPadding != null) || mCheckedPadding) {
return mConstantPadding;
}
createAllFutures();
Rect r = null;
final Rect t = new Rect();
final int N = mNumChildren;
final Drawable[] drawables = mDrawables;
for (int i = 0; i < N; i++) {
if (drawables[i].getPadding(t)) {
if (r == null) r = new Rect(0, 0, 0, 0);
if (t.left > r.left) r.left = t.left;
if (t.top > r.top) r.top = t.top;
if (t.right > r.right) r.right = t.right;
if (t.bottom > r.bottom) r.bottom = t.bottom;
}
}
mCheckedPadding = true;
return (mConstantPadding = r);
}