-
-
Save mswolters/9ffbdf01478e36194f8f to your computer and use it in GitHub Desktop.
public class TilingDrawable extends android.support.v7.graphics.drawable.DrawableWrapper { | |
private boolean callbackEnabled = true; | |
public TilingDrawable(Drawable drawable) { | |
super(drawable); | |
} | |
@Override | |
public void draw(Canvas canvas) { | |
callbackEnabled = false; | |
Rect bounds = getBounds(); | |
Drawable wrappedDrawable = getWrappedDrawable(); | |
int width = wrappedDrawable.getIntrinsicWidth(); | |
int height = wrappedDrawable.getIntrinsicHeight(); | |
for (int x = bounds.left; x < bounds.right + width - 1; x+= width) { | |
for (int y = bounds.top; y < bounds.bottom + height - 1; y += height) { | |
wrappedDrawable.setBounds(x, y, x + width, y + height); | |
wrappedDrawable.draw(canvas); | |
} | |
} | |
callbackEnabled = true; | |
} | |
@Override | |
protected void onBoundsChange(Rect bounds) { | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public void invalidateDrawable(Drawable who) { | |
if (callbackEnabled) { | |
super.invalidateDrawable(who); | |
} | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public void scheduleDrawable(Drawable who, Runnable what, long when) { | |
if (callbackEnabled) { | |
super.scheduleDrawable(who, what, when); | |
} | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public void unscheduleDrawable(Drawable who, Runnable what) { | |
if (callbackEnabled) { | |
super.unscheduleDrawable(who, what); | |
} | |
} | |
} |
I'm having an issue, the super() in the constructor warns
DrawableWrapper can only be called from within the same library group (groupId=com.android.support)
Similarly the getWrappedDrawable() in the draw(Canvas canvas) states
DrawableWrapper.getWappedDrawable can only be called from within the same library group (groupId=com.android.support)
Tried my Google-Fu, but very little results are online. Any help you can offer?
It seems an @RestrictTo
annotation was added to the class in the support library, so I think the only solution would be to copy the entire source of DrawableWrapper and subclass that.
Could you write a constructor for this class for tiling layout, simple "get started"?
Is it a correct example of use? At least, it work… :)
Drawable drawable = ContextCompat.getDrawable(this, R.drawable.my_drawable_resource); TilingDrawable tDraw = new TilingDrawable(drawable); tDraw.draw(new Canvas()); mRelativeLayout.setBackground(tDraw);
@antaki93 You can use this way on Kotlin:
yourView.background = TilingDrawable(AppCompatResources.getDrawable(this, R.drawable.your_drawable))
BTW, here's the original code of the TilingDrawable, in Kotlin:
open class DrawableWrapper(drawable: Drawable) : Drawable(), Drawable.Callback {
var wrappedDrawable: Drawable? = drawable
set(drawable) {
field?.callback = null
field = drawable
drawable?.callback = this
}
override fun draw(canvas: Canvas) = wrappedDrawable!!.draw(canvas)
override fun onBoundsChange(bounds: Rect) {
wrappedDrawable!!.bounds = bounds
}
override fun setChangingConfigurations(configs: Int) {
wrappedDrawable!!.changingConfigurations = configs
}
override fun getChangingConfigurations() = wrappedDrawable!!.changingConfigurations
override fun setDither(dither: Boolean) = wrappedDrawable!!.setDither(dither)
override fun setFilterBitmap(filter: Boolean) {
wrappedDrawable!!.isFilterBitmap = filter
}
override fun setAlpha(alpha: Int) {
wrappedDrawable!!.alpha = alpha
}
override fun setColorFilter(cf: ColorFilter?) {
wrappedDrawable!!.colorFilter = cf
}
override fun isStateful() = wrappedDrawable!!.isStateful
override fun setState(stateSet: IntArray) = wrappedDrawable!!.setState(stateSet)
override fun getState() = wrappedDrawable!!.state
override fun jumpToCurrentState() = DrawableCompat.jumpToCurrentState(wrappedDrawable!!)
override fun getCurrent() = wrappedDrawable!!.current
override fun setVisible(visible: Boolean, restart: Boolean) = super.setVisible(visible, restart) || wrappedDrawable!!.setVisible(visible, restart)
override fun getOpacity() = wrappedDrawable!!.opacity
override fun getTransparentRegion() = wrappedDrawable!!.transparentRegion
override fun getIntrinsicWidth() = wrappedDrawable!!.intrinsicWidth
override fun getIntrinsicHeight() = wrappedDrawable!!.intrinsicHeight
override fun getMinimumWidth() = wrappedDrawable!!.minimumWidth
override fun getMinimumHeight() = wrappedDrawable!!.minimumHeight
override fun getPadding(padding: Rect) = wrappedDrawable!!.getPadding(padding)
override fun invalidateDrawable(who: Drawable) = invalidateSelf()
override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) = scheduleSelf(what, `when`)
override fun unscheduleDrawable(who: Drawable, what: Runnable) = unscheduleSelf(what)
override fun onLevelChange(level: Int) = wrappedDrawable!!.setLevel(level)
override fun setAutoMirrored(mirrored: Boolean) = DrawableCompat.setAutoMirrored(wrappedDrawable!!, mirrored)
override fun isAutoMirrored() = DrawableCompat.isAutoMirrored(wrappedDrawable!!)
override fun setTint(tint: Int) = DrawableCompat.setTint(wrappedDrawable!!, tint)
override fun setTintList(tint: ColorStateList?) = DrawableCompat.setTintList(wrappedDrawable!!, tint)
override fun setTintMode(tintMode: PorterDuff.Mode) = DrawableCompat.setTintMode(wrappedDrawable!!, tintMode)
override fun setHotspot(x: Float, y: Float) = DrawableCompat.setHotspot(wrappedDrawable!!, x, y)
override fun setHotspotBounds(left: Int, top: Int, right: Int, bottom: Int) = DrawableCompat.setHotspotBounds(wrappedDrawable!!, left, top, right, bottom)
}
Thank you for sharing, that's very useful!
I've also added
, so wrapped drawable's size won't affect view's size.