下面列出了android.graphics.drawable.Drawable#setLayoutDirection() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Sets a drawable as the compound button image.
*
* @param drawable the drawable to set
* @attr ref android.R.styleable#CompoundButton_button
*/
public void setButtonDrawable(@Nullable Drawable drawable) {
if (mButtonDrawable != drawable) {
if (mButtonDrawable != null) {
mButtonDrawable.setCallback(null);
unscheduleDrawable(mButtonDrawable);
}
mButtonDrawable = drawable;
if (drawable != null) {
drawable.setCallback(this);
drawable.setLayoutDirection(getLayoutDirection());
if (drawable.isStateful()) {
drawable.setState(getDrawableState());
}
drawable.setVisible(getVisibility() == VISIBLE, false);
setMinHeight(drawable.getIntrinsicHeight());
applyButtonTint();
}
}
}
/**
* Sets the drawable displayed at each progress position, e.g. at each
* possible thumb position.
*
* @param tickMark the drawable to display at each progress position
*/
public void setTickMark(Drawable tickMark) {
if (mTickMark != null) {
mTickMark.setCallback(null);
}
mTickMark = tickMark;
if (tickMark != null) {
tickMark.setCallback(this);
tickMark.setLayoutDirection(getLayoutDirection());
if (tickMark.isStateful()) {
tickMark.setState(getDrawableState());
}
applyTickMarkTint();
}
invalidate();
}
/**
* Define the drawable used to draw the progress bar in indeterminate mode.
*
* @param d the new drawable
* @see #getIndeterminateDrawable()
* @see #setIndeterminate(boolean)
*/
public void setIndeterminateDrawable(Drawable d) {
if (mIndeterminateDrawable != d) {
if (mIndeterminateDrawable != null) {
mIndeterminateDrawable.setCallback(null);
unscheduleDrawable(mIndeterminateDrawable);
}
mIndeterminateDrawable = d;
if (d != null) {
d.setCallback(this);
d.setLayoutDirection(getLayoutDirection());
if (d.isStateful()) {
d.setState(getDrawableState());
}
applyIndeterminateTint();
}
if (mIndeterminate) {
swapCurrentDrawable(d);
postInvalidate();
}
}
}
/**
* @hide / public void clearMutated() { super.clearMutated();
* <p/>
* final ChildDrawable[] array = mLayerState.mChildren; final int N = mLayerState.mNum; for (int
* i = 0; i < N; i++) { final Drawable dr = array[i].mDrawable; if (dr != null) {
* dr.clearMutated(); } } mMutated = false; }
*/
@Override
public boolean onLayoutDirectionChanged(int layoutDirection) {
boolean changed = false;
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
final Drawable dr = array[i].mDrawable;
if (dr != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
changed |= dr.setLayoutDirection(layoutDirection);
}
}
updateLayerBounds(getBounds());
return changed;
}
/**
* Define the drawable used to draw the progress bar in progress mode.
*
* @param d the new drawable
* @see #getProgressDrawable()
* @see #setIndeterminate(boolean)
*/
public void setProgressDrawable(Drawable d) {
if (mProgressDrawable != d) {
if (mProgressDrawable != null) {
mProgressDrawable.setCallback(null);
unscheduleDrawable(mProgressDrawable);
}
mProgressDrawable = d;
if (d != null) {
d.setCallback(this);
d.setLayoutDirection(getLayoutDirection());
if (d.isStateful()) {
d.setState(getDrawableState());
}
// Make sure the ProgressBar is always tall enough
int drawableHeight = d.getMinimumHeight();
if (mMaxHeight < drawableHeight) {
mMaxHeight = drawableHeight;
requestLayout();
}
applyProgressTints();
}
if (!mIndeterminate) {
swapCurrentDrawable(d);
postInvalidate();
}
updateDrawableBounds(getWidth(), getHeight());
updateDrawableState();
doRefreshProgress(R.id.progress, mProgress, false, false, false);
doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false, false);
}
}
/**
* @hide
*/
@Override
public void onResolveDrawables(int layoutDirection) {
final Drawable d = mCurrentDrawable;
if (d != null) {
d.setLayoutDirection(layoutDirection);
}
if (mIndeterminateDrawable != null) {
mIndeterminateDrawable.setLayoutDirection(layoutDirection);
}
if (mProgressDrawable != null) {
mProgressDrawable.setLayoutDirection(layoutDirection);
}
}
/**
* 添加drawable, 如果id已经存在, drawable将会被替换
*
* @param id the drawable id.
* @param drawable the drawable.
* @return <code>true</code> - 如果添加成功, <code>false</code> - 其他
*/
public boolean addDrawable(int id, @NonNull Drawable drawable) {
DrawableInfo old = findAvatarDrawableById(id);
if (old != null) {
Drawable d = old.mDrawable;
old.mDrawable = drawable;
if (!hasSameDrawable(d)) {
cleanDrawable(d);
}
updateDrawableBounds(old);
} else {
if (getNumberOfDrawables() >= MAX_DRAWABLE_COUNT) {
return false;
}
mDrawables.add(crateAvatarDrawable(id, drawable));
layoutDrawables();
}
drawable.setCallback(this);
drawable.setVisible(getWindowVisibility() == VISIBLE && isShown(), true);
if (drawable.isStateful()) {
drawable.setState(getDrawableState());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
drawable.setLayoutDirection(getLayoutDirection());
}
invalidate();
return true;
}
private Drawable prepareDrawable(Drawable child) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
child.setLayoutDirection(mLayoutDirection);
}
child = child.mutate();
child.setCallback(mOwner);
return child;
}
ChildDrawable(ChildDrawable orig, LayerDrawable owner, Resources res) {
final Drawable dr = orig.mDrawable;
final Drawable clone;
if (dr != null) {
final ConstantState cs = dr.getConstantState();
if (res != null) {
clone = cs.newDrawable(res);
} else {
clone = cs.newDrawable();
}
clone.setCallback(owner);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
clone.setLayoutDirection(dr.getLayoutDirection());
clone.setBounds(dr.getBounds());
clone.setLevel(dr.getLevel());
} else {
clone = null;
}
mDrawable = clone;
mThemeAttrs = orig.mThemeAttrs;
mInsetL = orig.mInsetL;
mInsetT = orig.mInsetT;
mInsetR = orig.mInsetR;
mInsetB = orig.mInsetB;
mInsetS = orig.mInsetS;
mInsetE = orig.mInsetE;
mWidth = orig.mWidth;
mHeight = orig.mHeight;
mGravity = orig.mGravity;
mId = orig.mId;
}
/**
* Change the layout direction of the given drawable.
* Return true if auto-mirror is supported and drawable's layout direction can be changed.
* Otherwise, return false.
*/
@TargetApi(Build.VERSION_CODES.M)
private boolean mirror(Drawable drawable, int layoutDirection) {
if (drawable == null || !(C.API_KITKAT && drawable.isAutoMirrored())) {
return false;
}
if (C.API_MARSHMALLOW) {
drawable.setLayoutDirection(layoutDirection);
}
return true;
}
private void updateDrawable(Drawable d) {
if (d != mRecycleableBitmapDrawable && mRecycleableBitmapDrawable != null) {
mRecycleableBitmapDrawable.setBitmap(null);
}
boolean sameDrawable = false;
if (mDrawable != null) {
sameDrawable = mDrawable == d;
mDrawable.setCallback(null);
unscheduleDrawable(mDrawable);
if (!sCompatDrawableVisibilityDispatch && !sameDrawable && isAttachedToWindow()) {
mDrawable.setVisible(false, false);
}
}
mDrawable = d;
if (d != null) {
d.setCallback(this);
d.setLayoutDirection(getLayoutDirection());
if (d.isStateful()) {
d.setState(getDrawableState());
}
if (!sameDrawable || sCompatDrawableVisibilityDispatch) {
final boolean visible = sCompatDrawableVisibilityDispatch
? getVisibility() == VISIBLE
: isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown();
d.setVisible(visible, true);
}
d.setLevel(mLevel);
mDrawableWidth = d.getIntrinsicWidth();
mDrawableHeight = d.getIntrinsicHeight();
applyImageTint();
applyColorMod();
configureBounds();
} else {
mDrawableWidth = mDrawableHeight = -1;
}
}
/**
* Sets the thumb that will be drawn at the end of the progress meter within the SeekBar.
* <p>
* If the thumb is a valid drawable (i.e. not null), half its width will be
* used as the new thumb offset (@see #setThumbOffset(int)).
*
* @param thumb Drawable representing the thumb
*/
public void setThumb(Drawable thumb) {
final boolean needUpdate;
// This way, calling setThumb again with the same bitmap will result in
// it recalcuating mThumbOffset (if for example it the bounds of the
// drawable changed)
if (mThumb != null && thumb != mThumb) {
mThumb.setCallback(null);
needUpdate = true;
} else {
needUpdate = false;
}
if (thumb != null) {
thumb.setCallback(this);
if (canResolveLayoutDirection()) {
thumb.setLayoutDirection(getLayoutDirection());
}
// Assuming the thumb drawable is symmetric, set the thumb offset
// such that the thumb will hang halfway off either edge of the
// progress bar.
mThumbOffset = thumb.getIntrinsicWidth() / 2;
// If we're updating get the new states
if (needUpdate &&
(thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth()
|| thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) {
requestLayout();
}
}
mThumb = thumb;
applyThumbTint();
invalidate();
if (needUpdate) {
updateThumbAndTrackPos(getWidth(), getHeight());
if (thumb != null && thumb.isStateful()) {
// Note that if the states are different this won't work.
// For now, let's consider that an app bug.
int[] state = getDrawableState();
thumb.setState(state);
}
}
}
private static boolean setDrawableLayoutDirection(Drawable drawable, int layoutDirection) {
return Util.SDK_INT >= 23 && drawable.setLayoutDirection(layoutDirection);
}
/**
* Initializes a drawable for display in this container.
*
* @param d The drawable to initialize.
*/
private void initializeDrawableForDisplay(Drawable d) {
if (mBlockInvalidateCallback == null) {
mBlockInvalidateCallback = new BlockInvalidateCallback();
}
// Temporary fix for suspending callbacks during initialization. We
// don't want any of these setters causing an invalidate() since that
// may call back into DrawableContainer.
d.setCallback(mBlockInvalidateCallback.wrap(d.getCallback()));
try {
if (mDrawableContainerState.mEnterFadeDuration <= 0 && mHasAlpha) {
d.setAlpha(mAlpha);
}
if (mDrawableContainerState.mHasColorFilter) {
// Color filter always overrides tint.
d.setColorFilter(mDrawableContainerState.mColorFilter);
} else {
if (mDrawableContainerState.mHasTintList) {
DrawableCompat.setTintList(d, mDrawableContainerState.mTintList);
}
if (mDrawableContainerState.mHasTintMode) {
DrawableCompat.setTintMode(d, mDrawableContainerState.mTintMode);
}
}
d.setVisible(isVisible(), true);
d.setDither(mDrawableContainerState.mDither);
d.setState(getState());
d.setLevel(getLevel());
d.setBounds(getBounds());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
d.setLayoutDirection(getLayoutDirection());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
}
final Rect hotspotBounds = mHotspotBounds;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && hotspotBounds != null) {
d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top,
hotspotBounds.right, hotspotBounds.bottom);
}
} finally {
d.setCallback(mBlockInvalidateCallback.unwrap());
}
}