setCompoundDrawablesWithIntrinsicBounds 。最近喜欢上了看源码,感觉更能理解其中的逻辑,今天就来看下setCompoundDrawables 和setCompoundDrawablesWithIntrinsicBounds 在源码层次是怎么走的。
用代码给TextView设置drablew时,setCompoundDrawable方法没有起作用,原因是没有提前给Drawable设置setBounds。如果想手动设置大小的话就要用setCompoundDrawables,事先要给Drawable设置setBounds。 如果按照原有比例大小显示图片就使用setCompoundDrawablesWithIntrinsicBounds,在其内部,会按照原有比例进行setBounds操作,然后调用setCompoundDrawables方法进行设置。
setCompoundDrawablesWithIntrinsicBounds
/**
* Sets the Drawables (if any) to appear to the left of, above, to the
* right of, and below the text. Use {@code null} if you do not want a
* Drawable there. The Drawables' bounds will be set to their intrinsic
* bounds.
* <p>
* Calling this method will overwrite any Drawables previously set using
* {@link #setCompoundDrawablesRelative} or related methods.
*
*将Drawables(如果有的话)设置为在文本的右上右下。如果不想在那里使用Drawable,可以传一个{@code null}值。
* Drawables的边界将被设置为它们的固有边界。
*调用该方法将覆盖任何画板前面设置使用{@link # setCompoundDrawablesRelative}或相关的方法。
* @attr ref android.R.styleable#TextView_drawableLeft
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableBottom
*/
@android.view.RemotableViewMethod
public void setCompoundDrawablesWithIntrinsicBounds(@Nullable Drawable left,
@Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom) {
if (left != null) {
left.setBounds(0, 0, left.getIntrinsicWidth(), left.getIntrinsicHeight());
}
if (right != null) {
right.setBounds(0, 0, right.getIntrinsicWidth(), right.getIntrinsicHeight());
}
if (top != null) {
top.setBounds(0, 0, top.getIntrinsicWidth(), top.getIntrinsicHeight());
}
if (bottom != null) {
bottom.setBounds(0, 0, bottom.getIntrinsicWidth(), bottom.getIntrinsicHeight());
}
setCompoundDrawables(left, top, right, bottom);
}
setCompoundDrawables
/**
* Sets the Drawables (if any) to appear to the left of, above, to the
* right of, and below the text. Use {@code null} if you do not want a
* Drawable there. The Drawables must already have had
* {@link Drawable#setBounds} called.
* <p>
* Calling this method will overwrite any Drawables previously set using
* {@link #setCompoundDrawablesRelative} or related methods.
*
*将Drawables(如果有的话)设置为在文本的右边,在文本的右边。
*如果您不想在那里使用Drawable,请使用{@code null}。
*Drawables必须已经有{@link Drawable#setBounds}调用。
*调用此方法将覆盖前面所设置的任何可绘制项。
* { @link # setCompoundDrawablesRelative }或相关方法。
* @attr ref android.R.styleable#TextView_drawableLeft
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableBottom
*/
public void setCompoundDrawables(@Nullable Drawable left, @Nullable Drawable top,
@Nullable Drawable right, @Nullable Drawable bottom) {
Drawables dr = mDrawables;
// We're switching to absolute, discard relative.我们切换到绝对布局,不使用相对布局。
if (dr != null) {
// 如果图像不为空,
if (dr.mDrawableStart != null) dr.mDrawableStart.setCallback(null);
dr.mDrawableStart = null;
if (dr.mDrawableEnd != null) dr.mDrawableEnd.setCallback(null);
dr.mDrawableEnd = null;
dr.mDrawableSizeStart = dr.mDrawableHeightStart = 0;
dr.mDrawableSizeEnd = dr.mDrawableHeightEnd = 0;
}
final boolean drawables = left != null || top != null || right != null || bottom != null;
if (!drawables) {
// Clearing drawables... can we free the data structure?
// 回收drawables……我们可以自由的数据结构吗?
if (dr != null) {
if (!dr.hasMetadata()) {
mDrawables = null;
} else {
// We need to retain the last set padding, so just clear
// out all of the fields in the existing structure.
// 我们需要保留最后一组填充,所以需要清除回收已存在的结构。
for (int i = dr.mShowing.length - 1; i >= 0; i--) {
if (dr.mShowing[i] != null) {
dr.mShowing[i].setCallback(null);
}
dr.mShowing[i] = null;
}
dr.mDrawableSizeLeft = dr.mDrawableHeightLeft = 0;
dr.mDrawableSizeRight = dr.mDrawableHeightRight = 0;
dr.mDrawableSizeTop = dr.mDrawableWidthTop = 0;
dr.mDrawableSizeBottom = dr.mDrawableWidthBottom = 0;
}
}
} else {
if (dr == null) {
mDrawables = dr = new Drawables(getContext());
}
mDrawables.mOverride = false;
if (dr.mShowing[Drawables.LEFT] != left && dr.mShowing[Drawables.LEFT] != null) {
dr.mShowing[Drawables.LEFT].setCallback(null);
}
dr.mShowing[Drawables.LEFT] = left;
if (dr.mShowing[Drawables.TOP] != top && dr.mShowing[Drawables.TOP] != null) {
dr.mShowing[Drawables.TOP].setCallback(null);
}
dr.mShowing[Drawables.TOP] = top;
if (dr.mShowing[Drawables.RIGHT] != right && dr.mShowing[Drawables.RIGHT] != null) {
dr.mShowing[Drawables.RIGHT].setCallback(null);
}
dr.mShowing[Drawables.RIGHT] = right;
if (dr.mShowing[Drawables.BOTTOM] != bottom && dr.mShowing[Drawables.BOTTOM] != null) {
dr.mShowing[Drawables.BOTTOM].setCallback(null);
}
dr.mShowing[Drawables.BOTTOM] = bottom;
final Rect compoundRect = dr.mCompoundRect;
int[] state;
state = getDrawableState();
if (left != null) {
left.setState(state);
left.copyBounds(compoundRect);
left.setCallback(this);
dr.mDrawableSizeLeft = compoundRect.width();
dr.mDrawableHeightLeft = compoundRect.height();
} else {
dr.mDrawableSizeLeft = dr.mDrawableHeightLeft = 0;
}
if (right != null) {
right.setState(state);
right.copyBounds(compoundRect);
right.setCallback(this);
dr.mDrawableSizeRight = compoundRect.width();
dr.mDrawableHeightRight = compoundRect.height();
} else {
dr.mDrawableSizeRight = dr.mDrawableHeightRight = 0;
}
if (top != null) {
top.setState(state);
top.copyBounds(compoundRect);
top.setCallback(this);
dr.mDrawableSizeTop = compoundRect.height();
dr.mDrawableWidthTop = compoundRect.width();
} else {
dr.mDrawableSizeTop = dr.mDrawableWidthTop = 0;
}
if (bottom != null) {
bottom.setState(state);
bottom.copyBounds(compoundRect);
bottom.setCallback(this);
dr.mDrawableSizeBottom = compoundRect.height();
dr.mDrawableWidthBottom = compoundRect.width();
} else {
dr.mDrawableSizeBottom = dr.mDrawableWidthBottom = 0;
}
}
// Save initial left/right drawables 保存最初的左/右画板
if (dr != null) {
dr.mDrawableLeftInitial = left;
dr.mDrawableRightInitial = right;
}
resetResolvedDrawables();
resolveDrawables();
applyCompoundDrawableTint();
invalidate();
requestLayout();
}
网友评论