I have an image which I'm using as a background for a RelativeLayout. The image needs to be tiled horizontally to make a pattern.
I'm able to get the image to tile horizontally by using this code:
BitmapDrawable b3 = (BitmapDrawable)getResources().getDrawable(R.drawable.background);
b3.setTileModeX(Shader.TileMode.REPEAT);
v.findViewById(R.id.layout).setBackgroundDrawable(b3);
The problem is that the image also tiles vertically. It seems to tile in the "clamp" mode in the vertical, but "repeat" mode in the horizontal. Here is a screenshot:
As you can see, the image is just a little bit smaller than the space it occupies, and the bottom edge is "clamped".
How can I set the image to stretch vertically but tile horizontally?
This method invokes creation of new bitmap but it looks like it's acrhiving your goal
View view = findViewById(R.id.layout);
BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.tile);
int width = view.getWidth();
int intrinsicHeight = bd.getIntrinsicHeight();
Rect bounds = new Rect(0,0,width,intrinsicHeight);
bd.setTileModeX(TileMode.REPEAT);
bd.setBounds(bounds);
Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), bd.getBitmap().getConfig());
Canvas canvas = new Canvas(bitmap);
bd.draw(canvas);
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
view.setBackground(bitmapDrawable);
Please note that it only works if view was already layouted, so a method lile onWindowFocusChanged
is a good place for this code.
I feel it is straight forward:(This code will tile in Y and repeat in x)
In your onWindowFoucsChanged you call:
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
Drawable d = getRepeatingBG(this, R.drawable.image_that_you_want_to_repeat);
body_view.setBackgroundDrawable(d);
}
private Drawable getRepeatingBG(Activity activity, int center)
{
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled=true;
Bitmap center_bmp = BitmapFactory.decodeResource(activity.getResources(), center, options);
center_bmp.setDensity(Bitmap.DENSITY_NONE);
center_bmp=Bitmap.createScaledBitmap(center_bmp, dm.widthPixels , center_bmp.getHeight(), true);
BitmapDrawable center_drawable = new BitmapDrawable(activity.getResources(),center_bmp);
//change here setTileModeY to setTileModeX if you want to repear in X
center_drawable.setTileModeY(Shader.TileMode.REPEAT);
return center_drawable;
}
Far too late for you, but may be useful for others.
You can create a custom View in order to do this. Simply scale your source bitmap to be as high as your view and then draw it repeatedly on the canvas:
public class RepeatingXImageView extends View {
Bitmap bitmap;
Paint paint;
public RepeatingXImageView(Context context) {
super(context);
}
public RepeatingXImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RepeatingXImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if(changed) {
paint = new Paint();
bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.seekbar_overlay);
bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bottom - top, false);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(bitmap == null) return;
int left = 0;
while(left < getWidth()) {
canvas.drawBitmap(bitmap, left, 0, paint);
left += bitmap.getWidth();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With