下面列出了android.graphics.drawable.Drawable#setHotspotBounds() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected boolean setFrame(int l, int t, int r, int b) {
final boolean changed = super.setFrame(l, t, r, b);
// Set up the hotspot bounds to square and centered on the image.
final Drawable d = getDrawable();
final Drawable bg = getBackground();
if (d != null && bg != null) {
final int width = getWidth();
final int height = getHeight();
final int halfEdge = Math.max(width, height) / 2;
final int offsetX = getPaddingLeft() - getPaddingRight();
final int offsetY = getPaddingTop() - getPaddingBottom();
final int centerX = (width + offsetX) / 2;
final int centerY = (height + offsetY) / 2;
bg.setHotspotBounds(centerX - halfEdge, centerY - halfEdge,
centerX + halfEdge, centerY + halfEdge);
}
return changed;
}
/**
* Updates the thumb drawable bounds.
*
* @param w Width of the view, including padding
* @param thumb Drawable used for the thumb
* @param scale Current progress between 0 and 1
* @param offset Vertical offset for centering. If set to
* {@link Integer#MIN_VALUE}, the current offset will be used.
*/
private void setThumbPos(int w, Drawable thumb, float scale, int offset) {
int available = w - mPaddingLeft - mPaddingRight;
final int thumbWidth = thumb.getIntrinsicWidth();
final int thumbHeight = thumb.getIntrinsicHeight();
available -= thumbWidth;
// The extra space for the thumb to move on the track
available += mThumbOffset * 2;
final int thumbPos = (int) (scale * available + 0.5f);
final int top, bottom;
if (offset == Integer.MIN_VALUE) {
final Rect oldBounds = thumb.getBounds();
top = oldBounds.top;
bottom = oldBounds.bottom;
} else {
top = offset;
bottom = offset + thumbHeight;
}
final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
final int right = left + thumbWidth;
final Drawable background = getBackground();
if (background != null) {
final int offsetX = mPaddingLeft - mThumbOffset;
final int offsetY = mPaddingTop;
background.setHotspotBounds(left + offsetX, top + offsetY,
right + offsetX, bottom + offsetY);
}
// Canvas will be translated, so 0,0 is where we start drawing
thumb.setBounds(left, top, right, bottom);
}
private void setHotspot(float x, float y, Thumb thumb) {
if (thumb == null || thumb.getThumb() == null) return;
final Drawable background = getBackground();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && background != null) {
background.setHotspot(x, y);
Rect rect = thumb.getThumb().getBounds();
final int offsetY = getPaddingTop();
background.setHotspotBounds(rect.left, rect.top + offsetY,
rect.right, rect.bottom + offsetY);
}
}
@Override
public void draw(Canvas c) {
final Rect padding = mTempRect;
final int switchLeft = mSwitchLeft;
final int switchTop = mSwitchTop;
final int switchRight = mSwitchRight;
final int switchBottom = mSwitchBottom;
int thumbInitialLeft = switchLeft + getThumbOffset();
final Insets thumbInsets;
if (mThumbDrawable != null) {
thumbInsets = mThumbDrawable.getOpticalInsets();
} else {
thumbInsets = Insets.NONE;
}
// Layout the track.
if (mTrackDrawable != null) {
mTrackDrawable.getPadding(padding);
// Adjust thumb position for track padding.
thumbInitialLeft += padding.left;
// If necessary, offset by the optical insets of the thumb asset.
int trackLeft = switchLeft;
int trackTop = switchTop;
int trackRight = switchRight;
int trackBottom = switchBottom;
if (thumbInsets != Insets.NONE) {
if (thumbInsets.left > padding.left) {
trackLeft += thumbInsets.left - padding.left;
}
if (thumbInsets.top > padding.top) {
trackTop += thumbInsets.top - padding.top;
}
if (thumbInsets.right > padding.right) {
trackRight -= thumbInsets.right - padding.right;
}
if (thumbInsets.bottom > padding.bottom) {
trackBottom -= thumbInsets.bottom - padding.bottom;
}
}
mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom);
}
// Layout the thumb.
if (mThumbDrawable != null) {
mThumbDrawable.getPadding(padding);
final int thumbLeft = thumbInitialLeft - padding.left;
final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right;
mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
final Drawable background = getBackground();
if (background != null) {
background.setHotspotBounds(thumbLeft, switchTop, thumbRight, switchBottom);
}
}
// Draw the background.
super.draw(c);
}
@Override
protected void onDraw(Canvas canvas) {
final Drawable buttonDrawable = mButtonDrawable;
if (buttonDrawable != null) {
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int drawableHeight = buttonDrawable.getIntrinsicHeight();
final int drawableWidth = buttonDrawable.getIntrinsicWidth();
final int top;
switch (verticalGravity) {
case Gravity.BOTTOM:
top = getHeight() - drawableHeight;
break;
case Gravity.CENTER_VERTICAL:
top = (getHeight() - drawableHeight) / 2;
break;
default:
top = 0;
}
final int bottom = top + drawableHeight;
final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
final int right = isLayoutRtl() ? getWidth() : drawableWidth;
buttonDrawable.setBounds(left, top, right, bottom);
final Drawable background = getBackground();
if (background != null) {
background.setHotspotBounds(left, top, right, bottom);
}
}
super.onDraw(canvas);
if (buttonDrawable != null) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
if (scrollX == 0 && scrollY == 0) {
buttonDrawable.draw(canvas);
} else {
canvas.translate(scrollX, scrollY);
buttonDrawable.draw(canvas);
canvas.translate(-scrollX, -scrollY);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final Drawable checkMarkDrawable = mCheckMarkDrawable;
if (checkMarkDrawable != null) {
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int height = checkMarkDrawable.getIntrinsicHeight();
int y = 0;
switch (verticalGravity) {
case Gravity.BOTTOM:
y = getHeight() - height;
break;
case Gravity.CENTER_VERTICAL:
y = (getHeight() - height) / 2;
break;
}
final boolean checkMarkAtStart = isCheckMarkAtStart();
final int width = getWidth();
final int top = y;
final int bottom = top + height;
final int left;
final int right;
if (checkMarkAtStart) {
left = mBasePadding;
right = left + mCheckMarkWidth;
} else {
right = width - mBasePadding;
left = right - mCheckMarkWidth;
}
checkMarkDrawable.setBounds(mScrollX + left, top, mScrollX + right, bottom);
checkMarkDrawable.draw(canvas);
final Drawable background = getBackground();
if (background != null) {
background.setHotspotBounds(mScrollX + left, top, mScrollX + right, bottom);
}
}
}
@Override
public void draw(Canvas c)
{
final Rect padding = mTempRect;
final int switchLeft = mSwitchLeft;
final int switchTop = mSwitchTop;
final int switchRight = mSwitchRight;
final int switchBottom = mSwitchBottom;
int thumbInitialLeft = switchLeft + getThumbOffset();
final Insets thumbInsets;
if (mThumbDrawable != null)
{
thumbInsets = Insets.NONE;
}
else
{
thumbInsets = Insets.NONE;
}
if (mTrackDrawable != null)
{
mTrackDrawable.getPadding(padding);
thumbInitialLeft += padding.left;
int trackLeft = switchLeft;
int trackTop = switchTop;
int trackRight = switchRight;
int trackBottom = switchBottom;
if (thumbInsets != Insets.NONE)
{
if (thumbInsets.left > padding.left)
{
trackLeft += thumbInsets.left - padding.left;
}
if (thumbInsets.top > padding.top)
{
trackTop += thumbInsets.top - padding.top;
}
if (thumbInsets.right > padding.right)
{
trackRight -= thumbInsets.right - padding.right;
}
if (thumbInsets.bottom > padding.bottom)
{
trackBottom -= thumbInsets.bottom - padding.bottom;
}
}
mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom);
}
if (mThumbDrawable != null)
{
mThumbDrawable.getPadding(padding);
final int thumbLeft = thumbInitialLeft - padding.left;
final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right;
int offset = (AndroidUtilities.density == 1.5f ? AndroidUtilities.dp(1) : 0);
mThumbDrawable.setBounds(thumbLeft, switchTop + offset, thumbRight, switchBottom + offset);
final Drawable background = getBackground();
if (background != null && Build.VERSION.SDK_INT >= 21)
{
background.setHotspotBounds(thumbLeft, switchTop, thumbRight, switchBottom);
}
}
super.draw(c);
}
@Override
public void draw(Canvas c)
{
final Rect padding = mTempRect;
final int switchLeft = mSwitchLeft;
final int switchTop = mSwitchTop;
final int switchRight = mSwitchRight;
final int switchBottom = mSwitchBottom;
int thumbInitialLeft = switchLeft + getThumbOffset();
final Insets thumbInsets;
if (mThumbDrawable != null)
{
thumbInsets = Insets.NONE;
}
else
{
thumbInsets = Insets.NONE;
}
if (mTrackDrawable != null)
{
mTrackDrawable.getPadding(padding);
thumbInitialLeft += padding.left;
int trackLeft = switchLeft;
int trackTop = switchTop;
int trackRight = switchRight;
int trackBottom = switchBottom;
if (thumbInsets != Insets.NONE)
{
if (thumbInsets.left > padding.left)
{
trackLeft += thumbInsets.left - padding.left;
}
if (thumbInsets.top > padding.top)
{
trackTop += thumbInsets.top - padding.top;
}
if (thumbInsets.right > padding.right)
{
trackRight -= thumbInsets.right - padding.right;
}
if (thumbInsets.bottom > padding.bottom)
{
trackBottom -= thumbInsets.bottom - padding.bottom;
}
}
mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom);
}
if (mThumbDrawable != null)
{
mThumbDrawable.getPadding(padding);
final int thumbLeft = thumbInitialLeft - padding.left;
final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right;
int offset = (AndroidUtilities.density == 1.5f ? AndroidUtilities.dp(1) : 0);
mThumbDrawable.setBounds(thumbLeft, switchTop + offset, thumbRight, switchBottom + offset);
final Drawable background = getBackground();
if (background != null && Build.VERSION.SDK_INT >= 21)
{
background.setHotspotBounds(thumbLeft, switchTop, thumbRight, switchBottom);
}
}
super.draw(c);
}
@Override
protected void onDraw(Canvas canvas) {
// If there's text of any sort resort to CompoundButton#onDraw
if (getText() != null && getText().length() > 0 ||
getTextOff() != null && getTextOff().length() > 0 ||
getTextOff() != null && getTextOn().length() > 0) {
super.onDraw(canvas);
}
// Otherwise override CompoundButton#onDraw entirely to allow properly aligned image toggles
else {
final Drawable buttonDrawable = CompoundButtonCompat.getButtonDrawable(this);
if (buttonDrawable != null) {
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int horizontalGravity = getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK;
final int drawableHeight = buttonDrawable.getIntrinsicHeight();
final int drawableWidth = buttonDrawable.getIntrinsicWidth();
final int top;
switch (verticalGravity) {
case Gravity.BOTTOM:
top = getHeight() - drawableHeight;
break;
case Gravity.CENTER_VERTICAL:
top = (getHeight() - drawableHeight) / 2;
break;
default:
top = 0;
}
final int left;
switch (horizontalGravity) {
case Gravity.RIGHT:
case Gravity.END:
left = getWidth() - drawableWidth;
break;
case Gravity.CENTER_HORIZONTAL:
left = (getWidth() - drawableWidth) / 2;
break;
default:
left = 0;
}
final int bottom = top + drawableHeight;
final int right = left + drawableWidth;
buttonDrawable.setBounds(left, top, right, bottom);
final Drawable background = getBackground();
if (Build.VERSION.SDK_INT > 21 && background != null) {
background.setHotspotBounds(left, top, right, bottom);
}
buttonDrawable.draw(canvas);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
// If there's text of any sort resort to CompoundButton#onDraw
if (getText() != null && getText().length() > 0 ||
getTextOff() != null && getTextOff().length() > 0 ||
getTextOff() != null && getTextOn().length() > 0) {
super.onDraw(canvas);
}
// Otherwise override CompoundButton#onDraw entirely to allow properly aligned image toggles
else {
final Drawable buttonDrawable = CompoundButtonCompat.getButtonDrawable(this);
if (buttonDrawable != null) {
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int horizontalGravity = getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK;
final int drawableHeight = buttonDrawable.getIntrinsicHeight();
final int drawableWidth = buttonDrawable.getIntrinsicWidth();
final int top;
switch (verticalGravity) {
case Gravity.BOTTOM:
top = getHeight() - drawableHeight;
break;
case Gravity.CENTER_VERTICAL:
top = (getHeight() - drawableHeight) / 2;
break;
default:
top = 0;
}
final int left;
switch (horizontalGravity) {
case Gravity.RIGHT:
case Gravity.END:
left = getWidth() - drawableWidth;
break;
case Gravity.CENTER_HORIZONTAL:
left = (getWidth() - drawableWidth) / 2;
break;
default:
left = 0;
}
final int bottom = top + drawableHeight;
final int right = left + drawableWidth;
buttonDrawable.setBounds(left, top, right, bottom);
final Drawable background = getBackground();
if (Build.VERSION.SDK_INT > 21 && background != null) {
background.setHotspotBounds(left, top, right, bottom);
}
buttonDrawable.draw(canvas);
}
}
}
/**
* 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());
}
}
public static void setHotspotBounds(Drawable drawable, int left, int top,
int right, int bottom) {
drawable.setHotspotBounds( left, top, right, bottom);
}
/**
* As our DiscreteSeekBar implementation uses a circular drawable on API < 21
* we want to use the same method to set its bounds as the Ripple's hotspot bounds.
*
* @param drawable Drawable
* @param left Left
* @param top Top
* @param right Right
* @param bottom Bottom
*/
public static void setHotspotBounds(Drawable drawable, int left, int top, int right, int bottom) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//We don't want the full size rect, Lollipop ripple would be too big
int size = (right - left) / 8;
drawable.setHotspotBounds(left + size, top + size, right - size, bottom - size);
} else {
drawable.setBounds(left, top, right, bottom);
}
}